Secure Password Storage

March 20th, 2012

Tony Arcieri urges developers storing user-sensitive data, such as a passwords, not to use bcrypt (via Michael Tsai) for deriving the encryption key:

The first cipher I’d suggest you consider besides bcrypt is PBKDF2. It’s ubiquitous and time-tested with an academic pedigree from RSA Labs, you know, the guys who invented much of the cryptographic ecosystem we use today.

I was a little fuzzy on the distinction between encryption techniques such as AES, and the technology being discussed here, which is known as a key derivation function. Let’s break it down. With an encryption technique like AES you can use a large (e.g. 128 bits), difficult to guess private key to encrypt and decrypt data. But as a human, you can’t reasonably be expected to type in a random, 128-bit key in by hand when you want to access your data. The key derivation function is the code that takes your relatively easily-remembered password and derives a suitably monstrous, unpredictably random key from it. The quality and uncrackability of that key derivation is what Tony is questioning here.

I don’t know enough about encryption to have my own informed opinion about this. I tend to rely on the collective wisdom of the software industry, or on high-level service providers such as Apple, to suitably safeguard sensitive data in my apps. Tony included Apple’s FileVault full-disk-encryption in the list of technologies that use PBKDF2, which lent the technique an air of superiority in my mind. I know some of the folks behind Apple’s disk encryption, and they are careful, smart engineers.

I rely on FileVault for protection of my documents. But like most folks, I rely on Apple’s Keychain for the protection of passwords. I’m keenly interested to know if the Keychain is as secure as it reasonably can be, because I store not only my own passwords in it, but also e.g. my users’ blogging passwords in their respective keychains.

AgileBits, developers of the popular secure-storage app 1Password, made a conscious decision not to use Apple’s Keychain. They cite a variety of compelling reasons, including Keychain’s alleged use of a somewhat outdated encryption technique called Triple DES. Agile has written extensively about the design of their own keychain, in which they confirm that they are using PBKDF2 to derive their encryption keys.

I’m confident that Apple’s Keychain is secure for all practical purposes, but it is just sort of irksome if they are not adopting the very best protection that Mac-money can buy. Unable to find suitably authoritative documentation on the matter, I took to Apple’s open source for libsecurity_keychain, the library through which the Keychain’s data is managed. My reading of the source code for a function called SecKeyDeriveFromPassword, does show that Apple is indeed using PBKDF2 to generate the key.

On 10.7.3 they are, at least. The SecKeyDeriveFromPassword API was new to 10.7, taking over for the older CSSM_DeriveKey. Perhaps the default behavior of that function did not use PBKDF2. In any case, it sure sounds as if on top of Tony’s urging, FileVault’s use, and 1Password’s adoption of PBKDF2, Apple’s decision to use it as the mechanism in their latest versions of the Keychain only adds to the impression that it’s a fine choice.

10 Responses to “Secure Password Storage”

  1. Jean-Daniel Says:

    “An encryption technique like AES use a huge (e.g. 128 bits), extremely difficult to guess private key to decrypt data that was encrypted by another huge, but public key.”

    Arrggghh, AES is a symmetric algorithm. It does not use a public and a private key, but a single shared secret key.

    Moreover, 128 bits is very small for an asymmetric key, and can be guess easily, that’s why we use 1024 or 2048 bits for such key pair.

  2. Daniel Jalkut Says:

    Thanks, Jean-Daniel. You caught my ignorance very quickly ;) I’ve updated the example to cite RSA as the example algorithm and 1024-bits as the key size. Is that more believable?

  3. Jeffrey Goldberg Says:

    [Disclosure I am Chief Defender Against the Dark Arts at AgileBits, the makers of 1Password.]

    Thanks for bringing the importance of key derivation functions to more people’s attention. I’d like to clarify a couple of things that you do state correctly, but may not have come across all that clearly to readers.

    Key derivation functions serve two purposes. First they “stretch” a key. For example, AES uses a 128 bit key in most cases. Even a very good master password that someone comes up with is not going to be 128bits strong. So the first function of a key derivation is to turn a “stretch” a string of characters out to 128 bits (or whatever is needed).

    The second thing is that they are designed to slow things down. The process of getting from the password that people type in to the key should not happen too swiftly. This is to help slow down automated crackers.

    There is one other thing to note, an additional complication. For somethings (like a typical 1024 bit RSA key, or indeed the AES key that is used to encrypt 1Password data) are actually picked at random when the key is first set up. This key is then encrypted using something derived (through a key derivation function) from the user’s password. So your password (via PBKDF2) gets turned into a derived key, and this derived key is used to decrypt your actual, random, key.

    What this means is that people who have the same password, still don’t have the same key. It also means that the bulk of the encryption is performed with a really truly random key.

    Apple’s OS X keychain design has improved since the time we (at AgileBits) moved away from using it, and people should be very confortable storing credentials in it, as long as they understand that under default settings that keychain is protected by the users OS X login password.

    Cheers,

    -j

    –-
    Jeffrey Goldberg
    Chief Defender Against the Dark Arts @ AgileBits
    http://agilebits.com

  4. Dan Grassi Says:

    Here is a link to an image that provided security information for various key sized for both symmetric (DES, AES, etc) and asymmetric (RSA).

    http://zaph.com/images/security_strength.gif

    Generally it is believed that 128-bit AES is sufficient for the foreseeable future and the equivalent for RSA it 3072-bits so the best is to go to 4096-bits.

    Triple-DES can be either 112-bit or 168-bit with the 112-bit version common in electronic funds transfers. It is not bad if one stays away from a few weak keys (which one would expect of Apple.)

    Typically data is encrypted with symmetric encryption and keys are encrypted with asymmetric encryption.

    PBKDF2 is used for key derivation. Handling keys is a hard cryptography issue.

  5. Daniel Jalkut Says:

    Jeffrey & Dan – thanks for the great additional clarifications. It’s opening my eyes ever further.

  6. Allan Odgaard Says:

    In the case of RSA the (private) key is not derived from a typed password; it is read from disk, e.g. `~/.ssh/id_rsa` or the keychain (My Certificates).

    Derived keys are only for symmetric ciphers, though of course a private key itself is often encrypted with a symmetric cipher, thus requiring a “simple” password to use it.

  7. Daniel Jalkut Says:

    Allan – ah, thanks for that. I guess it makes sense that you only need a derived key when there needs to be a link to a simpler (i.e. passphrase) key.

  8. Daniel Jalkut Says:

    I decided to update the example back to AES to better support the symmetric encryption being discussed throughout the post. Hope I didn’t screw anything up :)

  9. Allan Odgaard Says:

    If you change “private key” to “secret key” there should be no terminology confusion.

  10. David Leppik Says:

    It’s worth noting that the original article doesn’t say bcrypt is bad, simply that there are better algorithms out there. The most important thing is to not use insecure hashes that look good but are really easy to crack– which is the first thing that naive programmers try. (If you’re going to use an md5 hash, why not go all the way and use rot-13? At least that way you’re not fooling yourself.)

    Quoth the source:

    “If you’re already using bcrypt, relax, you’re fine, probably. However, if you’re looking for a key derivation function (or in bcrypt’s case, password encryption function) for a new project, bcrypt is probably not the best one you can pick. In fact, there are two algorithms which are each better in a different way than bcrypt, and also widely available across many platforms.”

Comments are closed.

Follow the Conversation

Stay up-to-date by subscribing to the Comments RSS Feed for this entry.