If you've ever read Daniel V. Klein's paper (Foiling the Cracker: A Survey of, and Improvements to Unix Password Security) you may well be shocked at the number of users whose passwords were automatically guessed successfully.
In order to decrease the likelihood of my password being guessed, I've basically outlined how I make new passwords; I hope this may be of use to you. Suggestions are welcome.
I must take this opportunity to remind the reader that usage of this material is at their own risk. I cannot guarantee that by following the material here you will make ‘unguessable’ passwords; statistically, such things don't exist.
Methodology
- Find a good (pseudo) random number generator. The pseudorandom number generators provided with the standard C library, such as rand(3) or random(3), are probably not good enough, with the exception of OpenBSD's arc4random(3) (which uses kernel-collected entropy, and is the moral equivalent of reading from /dev/arandom).
- One way of achieving this by using an entropy gathering device built into Freenix kernels. OpenBSD has an excellent one called /dev/arandom, though on Linux and the other BSDs you can use /dev/urandom. I'd like to see kernel developers implement Yarrow-160, but that's another story.
- Pure binary data streams are not easy to enter though, so transform them appropriately—an 8-character Base64 password will provide up to 48 bits of entropy, and a 10-character Base85 password 64 bits.
- It'd be nice to have passwords of varying length (but of no less than 7 characters at any rate), but both the Base64 and Base85 encodings make this hard to do (requiring 4- and 5-character blocks respectively).
- Some people find that generating several passwords and picking one makes it easier to remember. While this may be true, the password is no longer random; the chosen password was picked because it's easier to remember, and that usually correlates with some aspect of memory. Better to generate one password, and use that.
Alternative methods
- Formerly I used the Unix crypt(3) function on random input and random salt. This requires that both be ‘quite random’, as above. If you use the last 11 characters from the string (i.e., excluding the salt), the resulting search space is 64 bits wide (6 bits each from the first 10 characters, 4 bits from the last). However, I do not know if the algorithm used reduces the entropy.
-
If you can use passphrases of a longer length (say, about 25.2 characters, on average[1], for a five-word passphrase), you should use Diceware instead. Using dice, you have no doubts about the randomness of the numbers, and you can roll as many dice as you want.
The 48- and 64-bit passwords above have slightly smaller search spaces than four- (51.7 bits) and five-word (64.6 bits) Diceware passphrases, respectively.
Implementation-specific issues
- If you read data from /dev/random or the like, use dd(1) or something that allows you to control the size of the reading buffer; e.g., use dd if=/dev/arandom bs=6 count=1 to generate 48 bits of random data. Don't use GNU head(1) to do it—it reads in 8 kilobyte blocks! (At least the textutils-2.0 implementation anyway.)
Footnotes
-
Using the English Diceware word list, the word frequences are:
| Word length | 1 | 2 | 3 | 4 | 5 | 6 |
| Frequency | 52 | 773 | 839 | 2345 | 3136 | 631 |
Hence, the expected length of a word is 4.24 characters, and so the expected length of a five-word passphrase, with a space between each word, is 25.2 characters.