I'm working on a java program to encrypt a string using AWS KMS key and AES_256 algorithm. I have used customer managed key from AWS KMS. When I encrypt the data, I'm getting an encrypted text. But when I tries to decrypt that encrypted text, I'm getting InvalidCiphertextException exception. Below is my code
`public String encrypt(String plaintext) throws Exception {
try {
// Generate AES key
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
SecretKey secretKey = keyGen.generateKey();
// Encrypt AES key with AWS KMS
EncryptRequest encryptKeyRequest = new EncryptRequest()
.withKeyId(keyId)
.withPlaintext(ByteBuffer.wrap(secretKey.getEncoded()));
EncryptResult encryptKeyResult = awsClient.encrypt(encryptKeyRequest);
byte[] encryptedKeyBytes = encryptKeyResult.getCiphertextBlob().array();
// Encrypt plaintext with AES
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(secretKey.getEncoded(), "AES"));
byte[] paddedPlaintext = addPadding(plaintext.getBytes(), cipher.getBlockSize());
byte[] encryptedBytes = cipher.doFinal(paddedPlaintext);
// Combine encrypted AES key and encrypted data for storage
byte[] combinedBytes = ArrayUtils.addAll(encryptedKeyBytes, encryptedBytes);
return Base64.encodeAsString(combinedBytes);
} catch (Exception e) {
System.err.println("Error encrypting the text: " + e.getMessage());
return null;
}
}
public String decrypt(String encryptedText) throws Exception {
try {
// Decode combined encrypted bytes
byte[] combinedBytes = Base64.decode(encryptedText);
// Extract encrypted AES key and encrypted data
int keySize = 32; // AES-256 key size in bytes
byte[] encryptedKeyBytes = new byte[keySize];
byte[] encryptedBytes = new byte[combinedBytes.length - keySize];
System.arraycopy(combinedBytes, 0, encryptedKeyBytes, 0, keySize-1);
System.arraycopy(combinedBytes, keySize, encryptedBytes, 0, encryptedBytes.length);
// Decrypt AES key with AWS KMS
DecryptRequest decryptKeyRequest = new DecryptRequest().withCiphertextBlob(ByteBuffer.wrap(encryptedKeyBytes));
DecryptResult decryptKeyResult = awsClient.decrypt(decryptKeyRequest);
byte[] decryptedKeyBytes = decryptKeyResult.getPlaintext().array();
// Decrypt data with AES
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptedKeyBytes, "AES"));
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
// Remove padding
byte[] unpaddedBytes = removePadding(decryptedBytes);
return new String(unpaddedBytes);
} catch (Exception e) {
System.err.println("Error decrypting the text: " + e.getMessage());
return null;
}
}
private static byte[] addPadding(byte[] data, int blockSize) {
int paddingSize = blockSize - (data.length % blockSize);
byte paddingByte = (byte) paddingSize;
byte[] paddedData = new byte[data.length + paddingSize];
System.arraycopy(data, 0, paddedData, 0, data.length);
for (int i = data.length; i < paddedData.length; i++) {
paddedData[i] = paddingByte;
}
return paddedData;
}
private static byte[] removePadding(byte[] data) {
int paddingSize = data[data.length - 1];
return ArrayUtils.subarray(data, 0, data.length - paddingSize);
}
`
I wish to know what went wrong with this implementation and is there any alternative way to handle this requirement other than this