+ // Close the temporary unencrypted export output stream.
+ temporaryUnencryptedExportOutputStream.close();
+
+ // Create an unencrypted export file input stream.
+ FileInputStream unencryptedExportFileInputStream = new FileInputStream(temporaryUnencryptedExportFile);
+
+ // Get the encryption password.
+ String encryptionPasswordString = encryptionPasswordEditText.getText().toString();
+
+ // Initialize a secure random number generator.
+ SecureRandom secureRandom = new SecureRandom();
+
+ // Get a 256 bit (32 byte) random salt.
+ byte[] saltByteArray = new byte[32];
+ secureRandom.nextBytes(saltByteArray);
+
+ // Convert the encryption password to a byte array.
+ byte[] encryptionPasswordByteArray = encryptionPasswordString.getBytes(StandardCharsets.UTF_8);
+
+ // Append the salt to the encryption password byte array. This protects against rainbow table attacks.
+ byte[] encryptionPasswordWithSaltByteArray = new byte[encryptionPasswordByteArray.length + saltByteArray.length];
+ System.arraycopy(encryptionPasswordByteArray, 0, encryptionPasswordWithSaltByteArray, 0, encryptionPasswordByteArray.length);
+ System.arraycopy(saltByteArray, 0, encryptionPasswordWithSaltByteArray, encryptionPasswordByteArray.length, saltByteArray.length);
+
+ // Get a SHA-512 message digest.
+ MessageDigest messageDigest = MessageDigest.getInstance("SHA-512");
+
+ // Hash the salted encryption password. Otherwise, any characters after the 32nd character in the password are ignored.
+ byte[] hashedEncryptionPasswordWithSaltByteArray = messageDigest.digest(encryptionPasswordWithSaltByteArray);
+
+ // Truncate the encryption password byte array to 256 bits (32 bytes).
+ byte[] truncatedHashedEncryptionPasswordWithSaltByteArray = Arrays.copyOf(hashedEncryptionPasswordWithSaltByteArray, 32);
+
+ // Create an AES secret key from the encryption password byte array.
+ SecretKeySpec secretKey = new SecretKeySpec(truncatedHashedEncryptionPasswordWithSaltByteArray, "AES");
+
+ // Generate a random 12 byte initialization vector. According to NIST, a 12 byte initialization vector is more secure than a 16 byte one.
+ byte[] initializationVector = new byte[12];
+ secureRandom.nextBytes(initializationVector);