我正在尝试在JAVA中实现AES / GCM / NoPadding加密和解密。使用的密钥是来自接收方的公钥和发送方的私钥(ECDH)的共享密钥。加密效果很好(有无iv)。但是,我无法解密......
我得到异常:javax.crypto.BadPaddingException:GCM中的mac检查失败
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()))));
}
答案 0 :(得分:1)
您必须使用完全相同的IV来加密和解密相同的密文,并且对于产生不同密文的每个加密,它必须是不同的。 IV不是秘密,因此您可以将其与密文一起发送。通常,它只是在密文之前预先填写并在解密之前切掉。
答案 1 :(得分:0)
您需要为两个Cipher.init调用提供GCMParameterSpec(包括IV)的实例。正如已经指出的那样,加密和解密的IV必须相同,并且必须是唯一的。