The main issue in your code was caused by a failure to specify an IV value. You must specify an IV value when doing CBC-mode encryption and use that same value when performing the CBC-mode decryption.
Another problem is the mix and match of creating strings from byte arrays and base64-encoding. You also return null from your decrypt method every time. Even if you meant return original.toString();, that’s still wrong (because toString() doesn’t do what you wish it would on a byte array).
Below is an improved version of your code. It’s far from optimal, but it compiles and works. You need to improve this to use a random IV. Also, if you plan to derive keys from passwords, don’t just get the bytes, use a derivation function such as PBKDF2. You can see an example of using PBKDF2 in the JNCryptor source.
public class EncryptionTest {
public static void main(String[] args) {
try {
String key = "ThisIsASecretKey";
byte[] ciphertext = encrypt(key, "1234567890123456");
System.out.println("decrypted value:" + (decrypt(key, ciphertext)));
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
}
public static byte[] encrypt(String key, String value)
throws GeneralSecurityException {
byte[] raw = key.getBytes(Charset.forName("UTF-8"));
if (raw.length != 16) {
throw new IllegalArgumentException("Invalid key size.");
}
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec,
new IvParameterSpec(new byte[16]));
return cipher.doFinal(value.getBytes(Charset.forName("UTF-8")));
}
public static String decrypt(String key, byte[] encrypted)
throws GeneralSecurityException {
byte[] raw = key.getBytes(Charset.forName("UTF-8"));
if (raw.length != 16) {
throw new IllegalArgumentException("Invalid key size.");
}
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec,
new IvParameterSpec(new byte[16]));
byte[] original = cipher.doFinal(encrypted);
return new String(original, Charset.forName("UTF-8"));
}
}