Symmetric Encryption
75
Password-based encryption in Java requires that we use two new classes in the javax.crypto.spec
package, PBEKeySpec and PBEParameterSpec, as well as javax.crypto.SecretKeyFactory.
PBEKeySpec
We use PBEKeySpec to create a key based on a password, using an instance of SecretKeyFactory. This
is one of the few classes in the JCE that we can actually call the standard constructor on. It takes a char
array as an argument due to the fact that passwords are typically not stored as strings, since strings are
immutable in Java, and there are times when you would like to be sure that a password is cleared out when
you're done using it. For more information, see Chapter 2 on writing secure code.
char[] password = "sasquatch".toCharArray();
PBEKeySpec keySpec = new PBEKeySpec(password);
SecretKeyFactory
In order to actually use the PBEKeySpec as a key, we need to run it through a SecretKeyFactory, which
will generate the key given a key specification, by calling generateSecret().
We create an instance of SecretKeyFactory by calling getInstance() with the name of the algorithm
we need. Here's an example of creating a SecretKey from a PBEKeySpec:
SecretKeyFactory keyFactory =
SecretKeyFactory.getInstance("PBEWithSHAAndTwofish-CBC");
SecretKey theKey = keyFactory.generateSecret(keySpec);
PBEParameterSpec
To create a cipher that uses PBE, we need to pass the salt and the iteration count to the cipher on
instantiation. PBEParameterSpec is a wrapper for that salt and iteration count. It is given to the cipher on
initialization, along with the key. Assuming the salt and iterations are already defined, here's how we would
get a cipher, using PBEParameterSpec:
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, iterations);
Cipher cipher = Cipher.getInstance("PBEWithSHAAndTwofish-CBC");
cipher.init(Cipher.ENCRYPT_MODE, theKey, paramSpec);
PBE Algorithm Names and Providers
You may have noticed the strange name for the algorithm that we used to initialize our key factory and
cipher above, PBEWithSHAAndTwofish-CBC. This specifies password-based encryption using SHA as a
message digest and Twofish in CBC mode as the symmetric encryption algorithm. There are a great
number of possible password-based encryption algorithms, including but not limited to:
PBEWithMD5AndDES
PBEWithSHAAndBlowfish
PBEWithSHAAnd128BitRC4
PBEWithSHAAndIDEA-CBC
PBEWithSHAAnd3-KeyTripleDES-CBC