I'm having trouble creating an encrypted string using AES/CBC/PKCS5Padding with a 128-bit key. I have code to decrypt an encrypted string. I have an example encrypted string from another system that decrypts successfully, but when I try to create my own encrypted string it is not padded properly for some reason. When I decrypt my encrypted string it only shows the characters after the 16 byte.
All of the examples I find either assume the encryption happens first then decryption happens right after that with variables set during encryption or they are randomly generating a key, but in my case i want to use a known key.
I am really stuck so any help would be greatly appreciated, thank you very much for your time and efforts!
Example:
Original Text: 01234567891234565
Encrypted: zmb16qyYrdoW6akBdcJv7DXCzlw0qU7A2ea5q4YQWUo=
Key length: 16
Decrypted: 5 (this is the last digit in the Original Text String)
Sample Code:
package com.company.encrypt.tests;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class TestEncryptDecrypt {
private static final String characterEncoding = "UTF-8";
private static final String cipherTransformation = "AES/CBC/PKCS5Padding";
private static final String aesEncryptionAlgorithm = "AES";
public static void main(String[] args) throws Exception {
String key1 = "1234567812345678";
String text = "01234567891234565";
System.out.println("Original Text: " + text);
String encrypted = encrypt(text, key1);
System.out.println("Encrypted: " + encrypted);
String decrypted = decrypt(encrypted, key1);
System.out.println("Decrypted: " + decrypted);
}
public static String decrypt(String encryptedText, String key) throws Exception {
String plainText = null;
int keyLength = key.length();
System.out.println("Key length: " + String.valueOf(keyLength));
byte[] encryptedTextBytes = Base64.decodeBase64(encryptedText.getBytes());
byte[] keyBytes = key.getBytes();
byte[] initialVector = Arrays.copyOfRange(encryptedTextBytes, 0, keyLength);
byte[] trimmedCipherText = Arrays.copyOfRange(encryptedTextBytes, keyLength, encryptedTextBytes.length);
try {
Cipher cipher = Cipher.getInstance(cipherTransformation);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, aesEncryptionAlgorithm);
IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] clearText;
clearText = cipher.doFinal(trimmedCipherText);
plainText = new String(clearText, characterEncoding);
} catch(NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException
| InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return plainText;
}
public static String encrypt(String plainText, String encryptionKey) throws Exception {
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), aesEncryptionAlgorithm);
Cipher cipher = Cipher.getInstance(cipherTransformation);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] plainTextBytes = plainText.getBytes("UTF-8");
byte[] encrypted = cipher.doFinal(plainTextBytes);
return new String(Base64.encodeBase64(encrypted));
}
}
byte[]- possibly by using a hexadecimal representation, or you should use password based encryption. - Maarten Bodewes