slow(&huge) password digest algorithm for GPG

Bernhard Kuemel bernhard at bksys.at
Sun Dec 12 05:00:55 CET 2004


Hi gnupg-devel!

gpg needs a slow algorithm to digest the passphrase before it 
decrypts the secret key. If it takes 1 s then dictionary or brute 
force attacks will be substantially slowed down and much shorter 
passphrases will suffice. I forgot my passphrase and now I need a 
new key. And a new passphrase. And a way to memorize or store it. 
Hmm, frequent use of gpg would help, but I don't have gpg 
integrated in mozilla yet ...

So ... I have some ideas about the passphrase digest:

<Basically>
the passphrase (together with a salt) is hashed with e.g. SHA1. 
The result is hashed, and we keep computing hashes from the 
previous hash until a user selected time like approximately 1 s 
has passed. The last hash (and the salt) is stored in the secret 
key and the secret key is encrypted with the second last hash.

When using the secret key the passphrase+salt is again hashed 
until a hash is produced that compares equal to the stored hash. 
The second last hash decrypts the secret key.

A dictionary or brute force attaker would test a passphrase by 
computing hashes until he finds a matching hash. But with a wrong 
passphrase he won't find one. So he has to stop and try another 
passphrase. If he stops too early he will not make it to the 
matching hash when trying the correct passphrase. So he has to 
pick a number of hashes which he assumes is likely to be larger 
than the one used by the user and that may well be twice as much.
</basically>

SHA1 (IMO) is a good choice here, as
1.) it is not easy to speed it up, because many people want a 
fast SHA1 so it is already well optimized. If a significantly 
faster version comes up it is easy to upgrade GPG (unless patents 
...)
2.) it has not shown cryptographic weaknesses for some time. 
Should it become possible to find the plain text for a given SHA1 
then the second last hash (which decrypts the secret key) could 
be found via the last hash stored in the secret key. I'm not sure 
if this is of concern as hashig typically loses information about 
the plain text (it must, if the plain text is larger than the 
hash). A solution should be to compute the new hash over the last 
2 hashes.

Another way to harden the scheme is to make it consume much 
memory. So the guys who build custom chips to crack keys will 
need lots of silicon. I'm not sure which way really requires an 
ideally configurable amount of memory preferably for the whole 
runtime. We could scatter the computed hashes over a buffer with 
configurable size and at the end pick some (non zero) samples 
which will be hashed and used to en/decrypt the secret key. But 
when making the buffer too big it will contain too much empty 
space and smart memory management may do with less memory. We 
could fill the memory with a pseudo random number generator, but 
smart memory management might supply this fill data where it 
previously only declared the managed empty space to be zero filled.
Maybe the internal state variables of the SHA1 algo can deliver 
more and fast high quality data to fill memory.

Hey, if we could find something useful to do instead of this 
trash, like seti at home or this cancer research project, that would 
be great. But I'm afraid that's incompatible with our goal.

I'm sorta tired now so any ideas I missed may come in future 
messages.

Bernhard



More information about the Gnupg-devel mailing list