This summer we’ve updated our guide to crypto security in Java from beginning to end, with new sections on crypto library bugs, frameworks, JDK and Bouncy Castle keystores, and more.
Over the past few months, we’ve been taking a look at the security of applications using the Java crypto API or Java Cryptographic Architecture (JCA), and examining the most commonly-used providers, Oracle JCE and BouncyCastle. Some of the results have been published in previous blog posts. We’ve decided to summarise all our findings in a free whitepaper.
From the intro:
This whitepaper is intended for developers who use, or are considering using, the Java crypto API, and for application security testers who review crypto security. It is not intended to be an introduction to cryptography, but rather a concise guide for readers familiar with crypto basics. We will tour the Java crypto API and explain common mistakes that cause security problems and crop up frequently in real applications.
We hope you find it useful – feedback is welcome. We’ll be updating the document in the future to cover some single sign-on protocol implementations and Java application framework crypto that we’ve been looking at recently, but suggestions for other topics are welcome.
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. Hence the Botticelli Venus above (and note the perfect logarithmic spiral of the curl on her right shoulder).
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.
To find these and other crypto security issues in Java applications, you can use our Analyzer software.
Java is probably the most widely-used programming language in the world. It certainly powers a large proportion of business applications. A million lines of code is a realistic codebase size. These applications use plenty of cryptography, to store passwords, encrypt database fields, communicate using TLS, and so on, often via the Java JCE/JCA crypto API. Many of them were first written a decade or more ago, so how secure is their crypto?
Our Cryptosense Analyzer is designed to help address this problem. It consists of a Java Agent that attaches itself to the JVM to make a trace of crypto calls, and an analysis engine that applies crypto usage rules to the resulting trace. This short demo video shows it in action. You can choose which rules you want to apply and filter on particular packages of interest.