Oh... just saw this. I already updated the wiki page with some stuff
based on another project that I'm working on. The design points in
there were provided by a security expert friend of mine. More below:
On Mon, Mar 26, 2012 at 11:45, Greg Hudson <ghudson_at_mit.edu> wrote:
> Unfortunately, there's more complexity in an encrypted password store
> than you probably anticipated, and it's definitely possible to lose
> some or most of your intended security properties if you get it wrong.
> The choice of best cipher algorithm today is very simple (AES,
> although you'll have to pick the key size from 128/196/256 bits), but
AES-256 in CBC mode was my buddy's suggestion.
> you do need to decide whether you want to be cipher-agile. Basically,
> if AES becomes a weak choice down the road (and it probably will,
> though it could be decades), is it better to be able to swap out the
> algorithm inside the password storage system, or better to just plan
> to swap out the system entirely for a redesigned one? Either position
> is defensible.
I'd suggest going with a single choice and leave it at that. It will
be good into the future, for as long as Subversion has existed in the
past. Security-conscious people can immediately switch once we provide
a new subsystem in ten years. Muggles will just naturally migrate as
the update their svn installation.
Keeping the implementation simple at this stage will be important. A
big chunk of Mike's work is to untangle the growth that has occurred
in the authn subsystem over the past ten years. The simplicity will
also help in a security review.
> You'll need to pick a function to map a passphrase to a crypto key.
> If you do a bad job, it will become easier to brute-force search for
> keys because your key distribution won't be even. To ensure even
> distribution, you typically need to use a hash function, which is an
> added dependency. String-to-key functions are also often deliberately
> slow, to make offline dictionary attacks harder. PBKDF2 (RFC 2898) is
> a reasonable choice here, and is implemented in some crypto libraries.
Agreed on PBKDF2. John mentioned the same thing, though I didn't need
it for my particular problem (I have no master passphrase; just needed
to securely store a bunch of passwords).
> You'll need to pick an appropriate cipher mode. If you simply use ECB
> (where you chunk the plaintext up into blocks and encrypt each block
> with the key), it will become easy to tell which passwords, or parts
> of passwords, are the same as which others. Maybe not a critical
> flaw, but certainly an avoidable one. If you use CTR (where you
> encrypt counter values with the key and XOR the result with the
> password), you'll need to make sure that counter values are never
> reused, or it will become easy to recover passwords with the key. CBC
> with a random initialization vector is also an option.
Per above, CBC mode was recommended. We can grab 128 bits of
cryptorandom data for the IV.
> If you don't use CTR mode, you'll need to pick a reversible padding
> function for the plaintext so that it matches a multiple of the
> cipher's block size. This is pretty simple.
In my wiki update, I mentioned 32 bits of random prefix (makes
dictionary attacks even harder), and pad with NUL characters. AES uses
16 byte blocks, and keys of 16/24/32 bytes.
> It's probably wise to look at what another implementation does. I'm
> not sure what password store implementations have made obvious
> mistakes and which ones haven't; I wish I had a better reference to
> give, but I don't know the state of the art for this particular
> application of crypto as well as others.
This should be quite doable, if we stick to a single, straightforward
design. Much of the pluggable stuff that is in the authn code can
probably be hauled into the "mainline" code now that we have more
experience. Certainly, breaking the link between authn algorithm and
data storage will help tremendously.
Received on 2012-03-26 19:29:10 CEST