Reputation: 6221
I am trying to implement AES/GCM/NoPadding encryption and decryption in JAVA .. the key used is a shared key from the public key of the receiver and the private key of the sender (ECDH).. encryption works well (with and without iv). However, I am unable to decrypt...
I get the exception: javax.crypto.BadPaddingException: mac check in GCM failed
public static String encryptString(SecretKey key, String plainText) throws NoSuchProviderException, NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
//IvParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");//AES/ECB/PKCS5Padding //"AES/GCM/NoPadding", "BC"
byte[] plainTextBytes = plainText.getBytes("UTF-8");
byte[] cipherText;
//cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
cipher.init(Cipher.ENCRYPT_MODE, key);
return new String(Base64.getEncoder().encode(cipher.doFinal(plainTextBytes)));
}
public static String decryptString(SecretKey key, String
cipherText) throws NoSuchProviderException,
NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, InvalidAlgorithmParameterException,
IllegalBlockSizeException, BadPaddingException,
UnsupportedEncodingException, ShortBufferException {
Key decryptionKey = new SecretKeySpec(key.getEncoded(),
key.getAlgorithm());
IvParameterSpec ivSpec = new IvParameterSpec(ivString.getBytes("UTF-8"));
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");//AES/GCM/NoPadding", "BC");
cipher.init(Cipher.DECRYPT_MODE, decryptionKey, ivSpec);
return new String (Base64.getEncoder().encode(cipher.doFinal(Base64.getDecoder().decode(cipherText.getBytes()))));
}
Upvotes: 0
Views: 13955
Reputation: 1
You need to supply an instance of GCMParameterSpec (which includes the IV) for both of the Cipher.init calls. As has already been pointed out, the IV has to be the same for both encryption and decryption, and must be unique.
Upvotes: 0
Reputation: 61892
You must use exactly the same IV for encryption and decryption of the same ciphertext and it must be different for each encryption that produces different ciphertexts. The IV is not secret, so you can send it along with the ciphertext. Usually, it is simply prepended to the ciphertext and sliced off before decryption.
Upvotes: 2