Wednesday 6 June 2012

Revelation password manager considered harmful (but now fixed)

UPDATE: It would appear that most of these issues have now been corrected in the latest version of Revelation, which is great. I leave the post below just for historical reference.

Personally, I have changed to using keepassx, which has some really nice features (like password auto-type) and has an Android app to go with it.



I am writing this post to draw attention to long-standing security issues in the revelation password manager.

I should start off by saying that I was not the first person to find these issues. Erik Grinaker, the original author, planned a new revelation file format to address some of these issues in 2009. However, it seems he stopped maintaining the project around that time. Later, Jakob Westhoff noted these security problems in a 2010 blog post and wrote a fork which improved the security (though probably not by enough), but it was not merged into the revelation mainline. After sitting unmaintained for over a year, Mikel Olasagasti Uranga became the new maintainer.

This security issue went more-or-less unnoticed until February this year when someone posted this issue on the revelation bug tracker. Despite being marked as a "critical" bug, it is still yet to be fixed, while plenty of less important things have been changed and new versions have been released.

As a user of revelation, I was first aware of Jakob's post last year, and while I found it quite concerning, I was busy and didn't do anything about it at the time. I also assumed that it was just a theoretical weakness and that I didn't have much to worry about. It wasn't really until now that I looked into it and saw just how serious this is. I posted on the revelation bug tracker today explaining the real-world implications for this.

To summarise, recent generations of desktop Intel processors can decrypt a 64 byte buffer (enough to test a key) with AES256 in under 384 cycles. Running 12 threads concurrently on a high-end desktop PC (6 cores, hyper-threaded, 3.9Ghz) could probably average 70 cycles per key tested, or about 55,714,285 keys/second. Checking to ensure we got the expected output would take a bit more time, so let's conservatively estimate that we can test 25,000,000 keys/second.

While it would take on the order of 1061 years to crack on average by guessing arbitrary 256 bit keys, revelation's implementation is so insecure that an alphanumeric (a-z A-Z 0-9) password with 8 characters can be cracked in a little over 7 weeks on average. This is because it just takes the password (worth not much more than ~50 bits) and sticks about 200 bits of zeros on the end (effectively cutting the time to crack the key by a factor of 2200.)

If that can be done with a single machine, imagine how fast it would be with a custom hardware solution. Yes, you may be using a more complicated password than 8 alphanumeric characters, but even still your plain text password is probably still crackable in a reasonable time-frame given enough resources.

Essentially, relatively short plain text passwords don't have anywhere near 256 bits of entropy. ASCII password characters have around 6-7 bits of entropy each, so even 10 characters will give you no more than 70 bits of entropy. The way to get around this is to make it slower to compute the key from the password text. Specifically, if testing a key requires K cycles to compute the key and D cycles to test it, changing to a more complicated key derivation function (KDF) K2 will effectively "add" log2(K2+D)-log2(K+D) bits of entropy.

While Erik's 2009 proposed file format mentions PBKDF2, a secure key derivation function, his pseudocode just uses 10,000 iterations of SHA256 without combining the salt or password into the hash function again. Jakob's fork was similar, and is probably not secure enough either. Given that revelation only needs to compute the key once (when the file is first opened), if it takes a second or two to open this would not be much of a problem.

With the CPU above where a key can be tested in 384 cycles, extending the key derivation to take ~1 second would add about 23 bits of effective entropy (though you'd probably want to base the timing on older hardware). Using a cryptographically secure salt would also prevent a collection of different revelation password databases being cracked simultaneously. Slowing the key testing by using memory-intensive algorithms would also likely be several orders of magnitude better than simple hashing iterations, since they render CPU caches ineffective and custom hardware attacks impractical (see scrypt, for example).

So, what should be done about this?
  1. As much as I love revelation, it is unacceptable to be using in its current form. Anyone using or distributing it should consider it as effectively compromised until it is fixed. As of today, I am going to look into other password managers to use until it is fixed (if you recommend any, please comment).
  2. The authors need to make it a priority to fix this. Essentially, revelation needs to use a better key derivation function (KDF). Furthermore, revelation should show the user their password strength for the database as it would when adding a password to the database. Since slowing down the key derivation can only add at most around 20 bits of entropy (about 3 characters worth), it's still important for users to choose long and varied passwords (between 15 and 20 characters) to give enough entropy for AES encryption. Furthermore, revelation could even time how long it takes to compute the key and decrypt the beginning of a file to guess, based on their password length/complexity, how many years it would take to crack if a machine with 1000x as much power were available. Anything that comes in at under 2000 years is much too weak (don't forget Moore's law.)
  3. Old password databases should be converted to the new format and for disclosure of this issue users should be notified that their old revelation password databases are potentially insecure and that they should attempt to update or erase any of their older databases.
  4. People need to spread the word in the Linux community about this.
UPDATE: Looking through the revelation code to see if any of the other formats revelation supports are more secure (many are, but not as much as I'd like; not many use salts that are long/varied enough or hashed properly), I discovered that the fpm exporter doesn't encrypt the passwords at all. Even though it asks the user for a password when exporting or importing, it actually only uses it to encrypt the version number, leaving everything else in plain text. Checking the source history, I found this has been broken since 2004.

I found that Martin Schwenke publicly posted a comment regarding this some time ago, so I don't consider this to be an irresponsible disclosure.

2 comments:

  1. Any recommendations on what to migrate to?

    ReplyDelete
  2. Good question. I'm still looking for something suitable. At the moment I've restricted the options to just two or three, but even these I'm still hesitant about. If I'm going to switch to another program for better security, I may as well make sure it's _really_ secure.

    Essentially, what I am looking for is:
    1) A fully encrypted file. Having just passwords encrypted leaves too much information about what you have passwords for.
    2) A key derivation of genuine difficulty. I like the idea of using a lot of memory to do this. Even 10MB or something is cheap for the majority of machines now, but puts a big limit on how quickly you can crack it.
    3) Good data handling practices; automatic re-locking if idle, minimising the amount of sensitive data in memory at any given point, ensuring that the process can't be ptrace()'d by userspace applications a.

    So far I can't find much with all three of these properties, so it may be a matter of finding which one would need the least work to make it secure.

    ReplyDelete