【发布时间】:2022-01-09 06:08:07
【问题描述】:
NodeJs:
我正在尝试使用 NodeJs 中的 AES CBC PKCS7 和 java 中的 PKCS5 解密文本。我收到错误:Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
更新
encrypt() {
var key = 'ThirtyTwoBytes3$ThirtyTwoBytes3$';
var iv = CryptoJS.enc.Utf8.parse(CryptoJS.lib.WordArray.random(128 / 8));
let utf8Pass = CryptoJS.enc.Utf8.parse("Hello");
let encVal = CryptoJS.AES.encrypt(utf8Pass.toString(), key, {mode:
CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, iv: iv});
return iv.concat(encVal.ciphertext).toString(CryptoJS.enc.Base64);
}
Java:
byte[] keyB = "ThirtyTwoBytes3$ThirtyTwoBytes3$".getBytes(StandardCharsets.UTF_8);
IvParameterSpec ivParameterSpec = new IvParameterSpec(encryptedText.getBytes(), 0, 16);
SecretKeySpec key = new SecretKeySpec(keyB, "AES");
Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding");
aesCBC.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
byte[] decryptedData = Base64.getDecoder().decode(encryptedText);
decryptedText = new String(Hex.decodeHex(new String(aesCBC.doFinal(decryptedData), StandardCharsets.UTF_8).toCharArray()));
固定 IV 工作正常
NodeJs
var encKey = CryptoJS.enc.Utf8.parse("ThirtyTwoBytes3$ThirtyTwoBytes3$");
var encKeyIv = CryptoJS.enc.Utf8.parse("$1SixteenBytes6$");
let utf8Pass = CryptoJS.enc.Utf8.parse("Hello");
let encVal = CryptoJS.AES.encrypt(utf8Pass.toString(), encKey, {mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, iv: encKeyIv});
encVal.ciphertext.toString();
Java:
SecretKey key = new SecretKeySpec("ThirtyTwoBytes3$ThirtyTwoBytes3$".getBytes(), "AES");
AlgorithmParameterSpec iv = new IvParameterSpec("$1SixteenBytes6$".getBytes());
byte[] decodeBase64 = Base64.decode(encVal);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, iv);
decString = new String(Hex.decodeHex(new String(cipher.doFinal(decodeBase64), "UTF-8").toCharArray()));
【问题讨论】:
-
不应该是
AES/CBC/PKCS7Padding吗?此外,您似乎将 16 个字节的密码作为 IV,然后解密整个内容?如果您的 CryptoJS 将 iv 附加到密码的开头,则密码不能包含 IV。通常虽然它会单独发送? -
@zaitsman 在 Java PKCS7 和 PKCS5 中是相同的。关于IV,是的,这就是我的想法。在加密字符串中,如果您看到我将前 16 读为 IV,则在我的 java 代码中应该加上前缀。但是在 NodeJs 中,我需要在返回之前明确附加它吗?我认为 Crypto 会照顾好
-
我会尝试对 IV 进行硬编码。如果您可以解密,您将知道您需要自己发送它。另外,回复:PKCS7 与 PKCS5 相同,严格来说并非如此:stackoverflow.com/questions/20770072/…
-
...但是在 NodeJs 中我需要在返回之前明确附加它吗?我认为 Crypto 会小心... 在您的用例中,
encrypted.toString()包含 Base64 编码的密文 没有 IV!您必须自己进行连接。此外,在 Java 中,PKCS#5 在此上下文中表示 PKCS#7。 -
@Topaco 我做了 IV 和 cypherText 的串联,但错误消息没有变化。尝试了固定 IV,效果很好
标签: node.js encryption aes java-11