6

I would like to implement a password creating program, similar to ones provided by Symantec and LastPass. This program will allow the user to simply specify different password lengths and options.

Are there any security considerations that should be made aside from using a proper cryptographically secure pseudo-random number generator in the algorithms? My plan was to use something like the RNGCryptoServiceProvider . "Secure random password generator" means one that is at least not backdoored or susceptible to frivolous flaws due to improper implementation. This is not a networked application.

Please note: I have no intention of "rolling my own" crypto or hashing.

  • 1
    Ok, well, that makes sense. Apologize if I was a little short-sighted in that regard as this Q will likely be viewed but many people in the future. Anyways, definitely don't worry about me, I'm a malware researcher and won't be releasing insecure products anytime soon :) – the_endian Mar 13 '17 at 18:07
  • 3
    I disagree with @StephenTouset that this is the "textbook definition" of rolling your own crypto. Random password generation can't be compared to inventing your own hashing algorithm. – Arminius Mar 13 '17 at 18:19
  • 2
    @StephenTouset From my understanding, OP is only interested in the password generation part, not storage, not distribution. An own password manager is obviously a different story. – Arminius Mar 13 '17 at 22:08
  • 1
    Yes I didn't mean a full scale application, im just talking about a generator here. I did mention it's not a networked application and that I wasn't planning on inventing any new crypto algorithms. I'm simply talking about generating some password strings. In fact, storage or transfer is not part of this at all. – the_endian Mar 13 '17 at 22:10
  • 1
    There are many open source password generators you could get the source for like pwgen, the generator in keypass and so on, which should give you a good starting point – Zoredache Mar 14 '17 at 0:40
6

Creating a secure password generator is fairly easy, provided you have two components:

  1. A cryptographically secure RNG. This means the output of the RNG is a bit stream that must not be predictable under any conditions. In most cases however, you can just use a PRNG designed specifically for key generation like /dev/urandom, /dev/random, or CryptGenRandom. Regular PRNG like Mersenne Twister should not be used for key generation. You should not attempt to write your own CSPRNG unless you have a deep background in CSPRNG mathematics. This is the part where most "regular people developing password generators" often don't really pay enough attention to.

  2. A one-to-one encoding algorithm. This algorithm encodes the bit stream produced by the RNG into something acceptable by the system that needs to use the password and, for memorizable password, the preference of the user. A one-to-one encoding is a function that does not have any output collisions for its inputs, so a the function does not lose any entropy produced by the RNG during the encoding. This is the part that is actually extremely easy, but most "regular people developing password generators" often overcomplicate unnecessarily, and end up weakening their password generation method.

Example of one-to-one encoding algorithm: Diceware, base64, hex encoding, any perfect hash function. Example of transformation algorithm not suitable for password generation: most regular hash algorithm.

Once you have these two components, all you need to do is ask the CSPRNG for a bit stream of length n, where n is the required strength of your password, and encode that bitstream using your selected encoding algorithm.

Pitfall: You should parameterize the encoding algorithm so it can never produce a password that would be rejected by the target system's password policy. If you simply reject a password and generate it again using different random value, you are reducing the entropy. In theory, this does mean that you will need to know the exact password policy detail of each system you need to generate for to correctly calculate your password strength. In practice, you can often simply add a few more bit strength to compensate for the entropy loss due to such overcomplicated password policy.

Pitfall: For memorizable passwords, the user must be trained not to reject any password that they end up finding hard to memorize as this also reduces the entropy. This means that memorizable password encoder should be designed as much as possible so that it produces passwords/paraphrases that's most likely to be accepted by the user in the first try. There are few encoding algorithms that attempts this, for example EFF Diceware wordlist or Grammatical Diceware.

  • So, essentially, the algorithm should be designed so that whatever the CSPRNG gives us is fully accepted by the system? If there are limitations on what is an acceptable password, then that should ideally be handled as part of the original CSPRNG mechanism rather than taking its output and then further filtering it with non-crypto-secure functions, which would reduce the entropy, thus defeating the purpose of the CSPRNG? ANd if this is not possible, we need a 1 to 1 encoding function which preserves the entropy – the_endian Mar 15 '17 at 3:40
  • No, the role of CSPRNG is to produce an extremely large n-bit number (i.e. a bitstream), where n is your password's bit strength. This huge number is your "real" password. The role of the encoding algorithm is to convert that huge number to something you can type, copy paste, possibly memorize, and which the password system could accept. What you want to avoid during encoding is causing entropy losses, which filtering/rejecting inputs and producing rejectable passwords would. You don't need to add entropy in the encoding step as the CSPRNG already produced all the entropy you need. – Lie Ryan Mar 15 '17 at 13:48
  • All this means is that the encoding simply needs to be a one-to-one (injective) function, from the CSPRNG output domain to the password system's input domain. It's not the role of the CSPRNG to understand what the password system would accept, the CSPRNG is simply a source of random bits. – Lie Ryan Mar 15 '17 at 13:49
  • Thanks for the link to the new EFF Diceware list. I had been using the old Diceware list to generate passwords for people at work and they were usually too vulgar or too creepy. – browly May 2 '17 at 19:53
2

The principle consideration for a password generator is that it doesn't produce predictable output. The point of random passwords is that the best attack against them is brute force, but if there's a bias, an attacker can take advantage to reduce their search space.

Along similar lines, often people want additional restrictions, like "pronounceable". This can be a security benefit (you can remember passwords instead of storing them) as well as a downside (introducing biases, see above). If you're interested in this, it's important to be very careful about not introducing extra bias into the algorithm, as that's a more complex problem than simply generating random characters.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.