I am in the process of creating an Android version of my Vault 3 application. Since Vault 3 optionally encrypts files using AES 128-bit keys, I had to ensure that a file encrypted using the desktop version of the program, which uses the Sun JVM, could be decrypted on an Android device. Here is the solution I came up with:
package com.ericbt.Vault3;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.List;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
* @author Eric Bergman-Terrell
*
*/
public class Temp {
private static byte[] getPasswordMessageDigest(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-512");
byte[] passwordMessageDigest = messageDigest.digest(password.getBytes("UTF-8"));
return passwordMessageDigest;
}
private static SecretKey createSecretKey(String password) throws NoSuchAlgorithmException, InvalidKeySpecException, UnsupportedEncodingException {
int keyLengthBits = 128;
int keyLengthBytes = keyLengthBits / 8;
String keyAlgorithm = "AES";
byte[] passwordMessageDigest = getPasswordMessageDigest(password);
Globals.getLogger().info(
String.format("Create Key: key length (bits): %d, key length (bytes): %d, algorithm: %s message digest length: %d",
keyLengthBits, keyLengthBytes, keyAlgorithm, passwordMessageDigest.length));
List passwordBytes = new ArrayList();
for (byte passwordByte : passwordMessageDigest) {
passwordBytes.add(passwordByte);
}
while (passwordBytes.size() < keyLengthBytes) {
passwordBytes.add((byte) 0);
}
while (passwordBytes.size() > keyLengthBytes) {
passwordBytes.remove(passwordBytes.size() - 1);
}
byte[] passwordByteArray = new byte[keyLengthBytes];
for (int i = 0; i < keyLengthBytes; i++) {
passwordByteArray[i] = passwordBytes.get(i);
}
SecretKey secretKey = new SecretKeySpec(passwordByteArray, keyAlgorithm);
return secretKey;
}
public static byte[] encrypt(String password, byte[] plainText) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, UnsupportedEncodingException {
SecretKey secretKey = createSecretKey(password);
Cipher cipher = Cipher.getInstance("AES");
Globals.getLogger().info(String.format("encrypt: cipher algorithm: %s", cipher.getAlgorithm()));
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] cipherText = cipher.doFinal(plainText);
Globals.getLogger().info("finished encryption");
return cipherText;
}
public static byte[] decrypt(String password, byte[] cipherText) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
SecretKey secretKey = createSecretKey(password);
Cipher cipher = Cipher.getInstance("AES");
Globals.getLogger().info(String.format("decrypt: cipher algorithm: %s", cipher.getAlgorithm()));
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] plainText = cipher.doFinal(cipherText);
Globals.getLogger().info("finished decryption");
return plainText;
}
}
| Title | Date |
| Node.js + Express: How to Block Requests by User-Agent Headers | January 7, 2026 |
| Vault 3 is Now Available for Windows on ARM Machines! | December 13, 2025 |
| Vault 3: How to Include Outline Text in Exported Photos | October 26, 2025 |
| .NET Public-Key (Asymmetric) Cryptography Demo | July 20, 2025 |
| Raspberry Pi 3B+ Photo Frame | June 17, 2025 |
| EBTCalc (Android) Version 1.53 is now available | May 19, 2024 |
| Vault 3 Security Enhancements | October 24, 2023 |