Symmetric Encryption 87 // Decrypt the key bytes byte[] decryptedKeyBytes = cipher.doFinal(encryptedKeyBytes); // Create the key from the key bytes SecretKeySpec key = new SecretKeySpec(decryptedKeyBytes, "Rijndael"); return key; } Now we can write the encrypt method. We start by loading the key with the loadKey() method we just wrote. Next we need to create an initialization vector that is 16 bytes long, equal to the block size of Rijndael. /** *   Encrypt a file using Rijndael. Load the key *   from the filesystem, given a password. */ private static void encrypt(char[] password, String fileInput, String fileOutput) throws Exception { System.out.println("Loading the key."); Key key = loadKey(password); System.out.println("Loaded the key."); // Create a cipher using that key to initialize it Cipher cipher = Cipher.getInstance("Rijndael/CBC/PKCS5Padding"); System.out.println("Initializing SecureRandom..."); // Now we need an Initialization Vector for the cipher in CBC mode. // We use 16 bytes, because the block size of Rijndael is 256 bits. SecureRandom random = new SecureRandom(); byte[] iv = new byte[16]; random.nextBytes(iv); Now we'll open the files for reading and writing. We'll write the IV bytes to the output file unencrypted, as we'll need to use it later to decrypt the file. Then we'll create an IVParameterSpec object that we will use to create a cipher. FileInputStream fis = new FileInputStream(fileInput); FileOutputStream fos = new FileOutputStream(fileOutput); // Write the IV as the first 16 bytes in the file fos.write(iv); IvParameterSpec spec = new IvParameterSpec(iv); System.out.println("Initializing the cipher."); cipher.init(Cipher.ENCRYPT_MODE, key, spec); Now we want to wrap a CipherOutputStream around the FileOutputStream using the cipher we just created: CipherOutputStream cos = new CipherOutputStream(fos, cipher);