A billion people have written about this before, but I like my approach, so I’m sharing it in case someone else finds it useful.
Most of my passwords go into a password manager; those are long and random and generated by the password manager and I don’t care whether they’re easy to type or memorable or whatever. However, there are a few passwords I have to type by hand, e.g., the one I use to unlock my computer and my password manager’s master password. I want those to have a decent length, be reasonably memorable, be reasonably easy for a touch-typist to type, and be complex enough to satisfy the complexity requirements of any policies that might be imposed upon me.
To accomplish that, I have a password generator script which prints out ten randomly generated passphrases — multiple words separated by hyphens — satisfying my requirements as outlined below. When I need to pick a new password, I run the script in a terminal window that isn’t logging its output anywhere, scan the list, pick the first one that I think I’ll be able to remember, and use it. If I don’t like any of the ten passwords the script prints, I just keep running it until I like one.
Here’s what the script does to generate the passwords:
- Suck up the contents of
/usr/share/dict/wordsto get a list of words from which passwords can be built.
- For each password being generated, start by randomly concatenating words together, separated by hyphens, until the password hits the minimum length (I use 12 characters).
- If the password already has a capital letter in it, then just use that; otherwise create variants of the password by separately capitalizing each of its words.
- If the password already has a number in it (some words in
/usr/share/dict/wordshave numbers in them), then just use that; otherwise create variants of the password by separately translating each of the characters
- Estimate how slow it is for a touch-typist to type each variant of the password based on how many repeat letters it has, how many keystrokes are required, and how often adjacent keystrokes are on the same hand. Keep the variant with the lowest typing complexity score.
- If the resulting complexity score is too high, throw away the password.
Once the script finds ten passwords with low enough complexity scores, it prints them out, sorted by complexity score, with the score for each password next to it.
These algorithm gives me passwords with at least one lower-case, upper-case, symbol (the hyphen!), and digit, ensuring that they will pass pretty much all password complexity policies.
Here is the script (yes, it’s a Perl script; when I wrote the first version of it, Python didn’t exist). Let me know (comment below or send me email) if you find it useful!