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