Giter VIP home page Giter VIP logo

go-password's Introduction

Golang Password Generator

GoDoc GitHub Actions

This library implements generation of random passwords with provided requirements as described by AgileBits 1Password in pure Golang. The algorithm is commonly used when generating website passwords.

The library uses crypto/rand for added randomness.

Sample example passwords this library may generate:

0N[k9PhDqmmfaO`p_XHjVv`HTq|zsH4XiH8umjg9JAGJ#\Qm6lZ,28XF4{X?3sHj
7@90|0H7!4p\,c<!32:)0.9N
UlYuRtgqyWEivlXnLeBpZvIQ
Q795Im1VR5h363s48oZGaLDa
wpvbxlsc

Since these are completely randomized, it's possible that they may generate passwords that don't comply with some custom password policies, such as ones that require both upper case AND lower case letters. If your particular use case needs a mix of casing, then you can either increase the number of characters in the password or check the output and regenerate if it fails a particular constraint, such as requiring both upper and lower case.

Installation

$ go get -u github.com/sethvargo/go-password/password

Usage

package main

import (
  "log"

  "github.com/sethvargo/go-password/password"
)

func main() {
  // Generate a password that is 64 characters long with 10 digits, 10 symbols,
  // allowing upper and lower case letters, disallowing repeat characters.
  res, err := password.Generate(64, 10, 10, false, false)
  if err != nil {
    log.Fatal(err)
  }
  log.Printf(res)
}

See the GoDoc for more information.

Testing

For testing purposes, instead of accepted a *password.Generator struct, accept a password.PasswordGenerator interface:

// func MyFunc(p *password.Generator)
func MyFunc(p password.PasswordGenerator) {
  // ...
}

Then, in tests, use a mocked password generator with stubbed data:

func TestMyFunc(t *testing.T) {
  gen := password.NewMockGenerator("canned-response", false)
  MyFunc(gen)
}

In this example, the mock generator will always return the value "canned-response", regardless of the provided parameters.

License

This code is licensed under the MIT license.

go-password's People

Contributors

infra-red avatar lpmi-13 avatar mkt avatar sethvargo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-password's Issues

Currently possible to generate a password without either uppercase or lowercase characters

While generating passwords, some password policies require both uppercase and lowercase letters. If the number of characters specified is low enough, there's a higher likelihood that a password with either no uppercase or no lowercase might be generated.

for example:

found one without uppers: lj<htui904&wgnobm2
found one without lowers: XS4M-VKG3BCQY+ET09
found one without lowers: P<QS8KTN53#BV1CDWY
found one without uppers: eab9ko!i45qc8tmny-
found one without lowers: SH-YC6Q*LBRM4FPD30

If it seems feasible, I'd love to submit a PR to update the behavior to avoid having either no uppercase or no lowercase in the generated strings, but not really sure where to begin. Any pointers much appreciated.

Concerns Regarding Entropy in Password Generation with Character Restrictions

The algorithm intends to produce high-entropy passwords, which suggests a high level of unpredictability and security. However, the restriction that disallows repeated characters and the requirement for a fixed number of digits and special characters may inadvertently reduce the entropy of the generated passwords.

Entropy, in the context of password security, is a measure of unpredictability or randomness. It is often quantified in bits and calculated based on the logarithm of the number of possible outcomes. For a password with n possible characters and a length of m, the total number of possible passwords without restrictions is n^m.

When we disallow repeated characters, we reduce the number of possible outcomes for each subsequent character. For example, if a password must be 8 characters long and we use a set of 62 possible characters (26 lowercase, 26 uppercase, 10 digits), the number of possible passwords without repetition is 62 * 61 * 61 * ... * 61, which is significantly less than 62^8.

Similarly, by fixing the number of digits and special characters, we further reduce the number of possible combinations. If a password must contain exactly 2 digits and 2 special characters, the positions and choices for these characters are limited, which reduces the overall entropy compared to a scenario where any character could occupy any position independently of their presence in other positions.

Mandating 2 digits in an 8-character alphanumeric password means that out of the 8 characters, exactly 2 must be digits (0-9) and the remaining 6 must be alphabetic characters (A-Z, a-z). This constraint reduces the number of possible combinations compared to a situation where all 8 characters could be freely chosen from the 62 possible alphanumeric characters (26 lowercase + 26 uppercase + 10 digits).

Let's calculate the number of possible passwords for both the constrained and unconstrained cases.

Unconstrained Case:
For each of the 8 characters, you can choose from 62 possibilities. Therefore, the total number of possible passwords is:
62^8

Constrained Case:
First, we need to choose the positions of the 2 digits in the 8-character password. There are C(8,2) ways to do this, where C(n,k) is the binomial coefficient representing the number of combinations of n items taken k at a time.

Once the positions for the digits are chosen, there are 10 possibilities for each digit. For the 6 alphabetic characters, there are 52 possibilities for each (26 lowercase + 26 uppercase). Therefore, the total number of possible passwords under the constraint is:
C(8,2) * 10^2 * 52^6

To calculate C(8,2), you can use the formula for the binomial coefficient:
C(n,k) = n! / (k!(n-k)!)

So, C(8,2) = 8! / (2! * (8-2)!) = 28

Thus, the total number of possible passwords with the constraint is:
28 * 10^2 * 52^6.

Suggestions

While it may seem counterintuitive, allowing characters to repeat increases the number of possible password combinations and thus the entropy. Obviously the user has the ability to specify this, but it is a rather detrimental option. The only justification I can think of is to comply with password requirements meant for human users. However, ignoring or removing the option may not be reasonable at this point.

Concatenation all characters from the character set(s) together and randomly selecting them one-by-one to produce the required password length could be a lot simpler and more secure. This could potentially be accomplished in a backwards-compatible way by interpreting negative numDigits and numSpecial as expecting this behavior.

randomInsert not fully random

Hi Seth, from what I can tell, the randomInsert function will never insert a character as the last character of the string.

README: add quick demo

Here is a quick demo to add to the README:

GO111MODULE=off go get github.com/sethvargo/go-password/password
go run github.com/dolmen-go/goeval@latest -i .=github.com/sethvargo/go-password/password 'fmt.Println(MustGenerate(14,2,2,false,true))'

Ability to override symbols seed

Lots of things don't allow all symbols (e.g., AWS IAM). It would be nice if the password.Symbols wasn't a constant so I can override it with my own valid symbol set.

Wrong password

In some cases got "wrong" passwords like:

	passwd, err := password.Generate(16, 8, 8, false, false)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf(passwd)
,48_$<723^05*=6%!(NOVERB)
?)~437\9}+%!&(MISSING)0618
239/1~%!,(BADINDEX)7_4{^06

Solved this by removing the % symbol from generate.go

The meaning of allowRepeat is not straightforward

According to the Generate docs:

allowRepeat allows characters to repeat.

People normally think of repeating characters as characters next to each other. For example, aba does not have repeating characters while aab does: a repeats twice.

The go-password use of allowRepeat means the same character cannot appear anywhere in the string a 2nd time. This can be thought of as allowing duplicate characters or only using unique characters.

To demonstrate, this will generate a password using all letters of the alphabet without duplicates.

res, err := password.Generate(26, 0, 0, true, false)

Increasing the length to 27 yields the following error;

2020/06/04 10:30:16 number of letters exceeds available letters and repeats are not allowed

The AgileBits 1Password link from the README states the repeating characters need to be consecutive, not unique to the entire password.

if doing do would lead to consecutive repeating characters. If it does, then we go back and pick a new character all together.

If you want to keep allowRepeats, I suggest renaming it to allowDuplicates or onlyUnique.

v0.2.0 does not appear in Releases

Although v0.2.0 appears in tags, and therefore can be downloaded via golang's module system, it is confusing when looking on Github's releases page, which still lists v0.1.2 as the latest.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.