Password purgatory

,

Since the Heartbleed bug rendered all our passwords insecure, we’ve all been going through the purgatory of upgrading servers and changing passwords. This isn’t the first time I’ve done a mass-reset of my passwords, but I thought I’d try something new. This time I’m seeing what it’s like to try to follow “best practices,” which I understand to be:1

  1. Use a different password for each service.

  2. Generate passwords using a process that ensures they have an adequate number of bits of entropy.

  3. Don’t write them down or store them unencrypted.

  4. If you have more passwords than you can remember, use a keychain program.

  5. Use single-sign-on technologies like OpenID to reduce the number of passwords and accounts.

… but I find myself wondering if these practices are really suitable for human beings?

Kerckhoffs’ principle is that a good cryptosystem remains secure if everything about the system (excepting the key) is public knowledge, so hopefully I won’t be compromising everything by explaining what I do.2 For passwords that have to be memorable I use random passphrases on the diceware principle (popularized by Randall Munroe3), generated like this (using shuf from the GNU coreutils package):

egrep '^.{4,9}$' /usr/share/dict/words | shuf -n4 --random-source=/dev/random

The egrep is there to keep the words short enough to be typeable: my typing is not good enough to reliably enter something like Protorosauridae quinquevalvular intraformational horticulturist when I can’t see what I’m doing. Given the number of words of 4–9 letters in the system dictionary:

$ egrep -c '^.{4,9}$' /usr/share/dict/words
119469

these passwords have about 4·log2119469 = about 67 bits of entropy, but it usually takes me a few tries before I get one that I am confident that I can memorize, so maybe 64 bits of entropy would be a good estimate.4

There’s a very limited number of these passwords that I can remember—realistically about two—so already I’m stuck: my login password on each computer must be memorable (because there’s no access to the keychain until I’m logged in) and so must my keychain password (obviously), so just one computer would use up my memorable passwords, and then I’m not following best practice any more. What do the “best practice” people do about this? Use less secure passwords? I guess that if I used half as many bits of entropy I could remember twice as many passwords, but 32 bits of entropy is well within the realm of brute force cracking.) Anyway, what I do is reuse the login password as the keychain password.

All the other passwords have to go in the keychain. These passwords don’t have to be memorable, so at least they might as well be secure. I use:

base64 -b 16 /dev/random | head -1

which produces passwords with 16·6 = 96 bits of entropy, which seems like plenty, given that I’m going to be using these on buggy web browsers on buggy operating systems.

How do I get these passwords from one computer to another? Best practice is not to write them down. I certainly wouldn’t print them out: I don’t trust the software on printers. If I trusted online services like LastPass or Apple’s iCloud Keychain then I could use those, but I’d rather not if I can avoid it.5 So I use gpg to encrypt a file of passwords (using one of my memorable passwords) and then transfer it using scp.

For web passwords, having your password in the system keychain works pretty well—the browser collaborates with the keychain to store and retrieve the password when necessary. But for other applications it’s a pain. For example, why doesn’t iTunes offer to store the password for my Apple ID in the keychain? Sure, I can go to Keychain Access and retrieve the password and copy and paste it, but it feels like busy-work.

And then there’s Perforce. Each morning I sit down at my desk, open up Emacs and type C-x p g to bring my client workspace up to date, and each morning the Perforce client discovers that my authentication ticket, issued the previous day, has expired, and prompts me for my password.6 So how can I get my password out of the keychain and into Perforce?7 Well, this week I learned that OS X comes with the very handy security command:

security(1)               BSD General Commands Manual              security(1)

NAME
     security -- Command line interface to keychains and Security framework

SYNOPSIS
     security [-hilqv] [-p prompt] [command] [command_options] [command_args]

DESCRIPTION
     A simple command line interface which lets you administer keychains,
     manipulate keys and certificates, and do just about anything the Security
     framework is capable of from the command line.

With this command, you can add password to the keychain on the command line like this:

security add-generic-password -s test-password -a user -w password

This corresponds to selecting File → New Password Item… (or typing ⌘N) in Keychain Access and filling in the form like so:

Now the password can be retrieved from the keychain like this:

security find-generic-password -s test-password -a user -w

which pops up the familar window:

So Perforce can be accommodated by creating keychain items for each Perforce account, and then piping the retrieved password to p4 login:

security find-generic-password -s $P4PORT -a $P4USER -w | p4 login

On some Linux distibutions (for example, Ubuntu), the equivalent of Keychain Access is GNOME Keyring. But how do you get at this from the command line? (Preferably without installing anything.) Well, the best method that I have been able to discover is to use the keyring Python module. To add a password to the keyring, run this Python program:

import keyring, sys; keyring.set_password(*sys.argv[1:])

passing SERVER, USER and PASSWORD as the three command-line arguments. (This does not seem to correspond to any action you can take via the built-in “Passwords and Keys” application on Ubuntu, which has no facility for setting the SERVER and USER fields.) To retrieve the password, run this Python program:

import keyring, sys; print(keyring.get_password(*sys.argv[1:]))

passing SERVER and USER on the command line. (The keyring module also supports the OS X keychain, but it’s not as convenient as security because it’s not installed by default on OS X.)

But what about Windows? The system feature is “Credential Manager” and the Windows API calls to store and retrieve items seem to be CredWrite() and CredRead(), but how do I call them from the command line? Embedded C# in PowerShell? Any help you can give this Windows n00b would be appreciated.


  1.  See best practices from Microsoft, NIST, Bruce Schneier.

  2.  But if you spot that I’ve slipped up somewhere, do hit me with the clue stick.

  3.  Bruce Schneier says that this approach is no good: “the oft-cited XKCD scheme for generating passwords—string together individual words like ‘correct horse battery staple’—is no longer good advice. The password crackers are on to this trick.” But I don’t understand his reasoning: surely it doesn’t matter if the password crackers are on to the trick, so long as there is enough entropy in the password?

  4.  Diceware are now recommending that your passphrase consist of six random words from their list (about 77 bits of entropy)—they believe that five (about 64 bits) is no longer secure against the most determined and capable attackers.

  5.  The lesson from Lavabit and similar cases is that it’s not enough for the service to be ethical and technically competent if it can be compelled to disclose your data.

  6.  This is at least an improvement over the state of affairs before I started working on the Perforce/Emacs integration. Automatic prompting for login (#7) was the third most important issue for me after blocking opening of files (#34) and losing edits (#1).

  7.  Issue #168.