Paranoia and Java Cryptography
By me on May 16, 2009
I started looking at rewriting a web app I wrote a while ago that does encryption in Java. This time trying to pay more attention to crossing the T's and dotting the I's, and I'm realizing encryption in Java is tricky.
The JCE itself makes things pretty easy, however where it gets a little tricky is how to deal with discarded information - passphrases, private keys, unencrypted data - when you are done with it. Unlike C code, for example, where you can simply zero out portions of memory when you are done with it, Java has very little available to do the same thing.
And it can get worse, when you are dealing with Strings, for example, they can get stuffed into a master String table - via String.intern(), squirreled away in the far reaches of the JDK, with no ability to destroy them. Thus, at the very least, never convert any sensitive information to a String, if you want any hope of ever clearing it out of memory.
The JCE designers seem to have been pretty keen to this, and provide interfaces that never use Strings as any parameters that could be sensitive. A good foundation, however dealing sensitive data elsewhere can be tricky.
A simple example, back to the web app, is dealing with parameters in a servlet. Say you have a servlet which takes a passphrase and a chunk of text and encodes it. Normally you retrieve parameters in a servlet with HttpServletRequest.getParameter(String name). The problem: getParameter() returns a String, and thus could get stuffed into the JVMs String table for ever more.
Although it would be unlikely for someone to gain access to the String table, and then figure out which String actually represented a passphrase, the paranoid side in me makes me a little nervous to allow that sensitive information to exist out of my control.
Even worse, the unencrypted data that you want to encrypt. Again, if you retrieve it with getParameter(), you won't be able to fully discard the unencrypted data until you restart the JVM.
I haven't quite figured out a plan for how paranoid I want to be. One thought would be to instantiate a new ClassLoader to manipulate sensitive data. Presumably when you get rid of the ClassLoader all the classes (including the String table) would at least be eligible for garbage collection.