If you write a Java application that uses cryptography, chances are you’ll have to store some cryptographic keys. The Java crypto APIs provide an abstraction for dealing with this called keystores. In this post, we’re going to look into how Java keystores are protected when written out as files.
In fact there are several kinds of Java keystore, and different Java crypto providers implement them in different ways, resulting in files that are more or less resistant to attack. For example, in the Sun crypto provider, there is the “JKS” old-style Sun keystore, the “JCEKS” new(-ish) style Sun keystore, and a PKCS12 compatible keystore. Other providers like BouncyCastle offer their own variations.
When it comes to protecting fields containing the keys, all of these keystores function by some kind of password-based encryption (PBE). If an encryption password is given (and it’s not always mandatory to do so), this is used to derive a key that’s then used to encrypt the file containing the serialization of the keys.
Hold the Salt
In the old-style Sun JKS keystore, the PBE method is somewhat unconventional. Individual keys are XORed against a keystream derived by applying SHA-1 repeatedly to the password and a 20 byte salt. Only one SHA-1 application is required to derive the first keystream byte. Since DER encoded keys contain a lot of structure in their first bytes, we can work out what the first few bytes of the hashed password must be, which makes a dictionary-based cracker highly efficient.
As a final quirk, an integrity signature is calculated over the encrypted keystore by hashing the password, the keystore, and the US-ASCII string “Mighty Aphrodite”. Nobody seems to know why, but perhaps it dates the design back to 1995, when the Woody Allen film of the same name was in the cinemas, and the first Java beta release was made.
It should be clear that you must not use these legacy techniques to protect real keys in today’s environments. It’s one of the keystore-related weaknesses we detect with our Java Crypto App Tracer, and we come across it it quite often. There’s simply a lot of Java code in production that has not been audited for crypto security since it was written 15 years ago or more.
More Keystore Attacks
You can find out more about keystore security and other Java crypto security issues in our free whitepaper.