Chapter 4 86 Now we can use the cipher to encrypt the encoded form of the key: // Encrypt the key byte[] encryptedKeyBytes = cipher.doFinal(key.getEncoded()); In order to be able to decrypt the key, we need to have the salt. We'll write the salt that we generated to the first 8 bytes of the file, and then we'll write the encrypted key and close the file. // Write out the salt, and then the encrypted key bytes FileOutputStream fos = new FileOutputStream(KEY_FILENAME); fos.write(salt); fos.write(encryptedKeyBytes); fos.close(); } Before we can do any file encryption or decryption, we'll need to have access to the key. We're going to write a method called loadKey() that will load a key, with a password specified as an argument. This is essentially the reverse of the createKey() method: we read in the salt, and the encrypted key bytes, and then decrypt the key with a PBE cipher. We'll use javax.crypto.spec.SecretKeySpec to create a key from the decrypted key bytes. /** *   Loads a key from the filesystem */ private static Key loadKey(char[] password) throws Exception { // Load the bytes from the encrypted key file. FileInputStream fis = new FileInputStream(KEY_FILENAME); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int i = 0; while ((i=fis.read()) != -1) { baos.write(i); } fis.close(); byte[] saltAndKeyBytes = baos.toByteArray(); baos.close(); // Get the salt, which is the first 8 bytes byte[] salt = new byte[8]; System.arraycopy(saltAndKeyBytes,0,salt,0,8); // get the encrypted key bytes int length = saltAndKeyBytes.length - 8; byte[] encryptedKeyBytes = new byte[length]; System.arraycopy(saltAndKeyBytes,8,encryptedKeyBytes,0,length); // Create the PBE cipher PBEKeySpec pbeKeySpec = new PBEKeySpec(password); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance( "PBEWithSHAAndTwofish-CBC"); SecretKey pbeKey = keyFactory.generateSecret(pbeKeySpec); PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, ITERATIONS); Cipher cipher = Cipher.getInstance("PBEWithSHAAndTwofish-CBC"); cipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec);