1

我正在尝试解密使用 CryptoJS 加密的 java 中的文本。我在其他帖子上读过它们使用不同的默认模式和填充,所以我将它们(java/cryptojs)都设置为使用 aes/cbc/nopadding。我不再在 java 中遇到异常,但在解密期间我得到一个乱码输出

加密(JS):

var parsedLogin = JSON.parse(login);
var publicKey = "abcdefghijklmnio";
var publiciv =  "abcdefghijklmnio";
var key = CryptoJS.enc.Hex.parse(publicKey);
var iv = CryptoJS.enc.Hex.parse(publiciv);
var encrypted = CryptoJS.AES.encrypt(parsedLogin.password, publicKey, {iv: publiciv}, { padding: CryptoJS.pad.NoPadding, mode: CryptoJS.mode.CBC});

// send encrypted to POST request 

解密(Java)

String PUBLIC_KEY = "abcdefghijklmnio";
String PUBLIC_IV = "abcdefghijklmnio";
byte[] byteArr = PUBLIC_KEY.getBytes();
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
final SecretKeySpec secretKey = new SecretKeySpec(byteArr, "AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(PUBLIC_IV.getBytes()));

byte[] parsed = Base64.decodeBase64(encrypted.getBytes());
//byte[] parsed = DatatypeConverter.parseBase64Binary(encrypted); 

byte[] fin = cipher.doFinal(parsed);
String decryptedString = new String(fin);

我得到的结果是这样的:Š²Û!aå{'`@"Ûîñ?Œr~krÆ

我已经尝试将 getBytes() 中的 CHARSET 更改为 US-ASCII、UTF-8 和 UTF-16,但这所做的只是更改乱码文本

我也尝试过使用其他阻塞模式和填充,但它们在 js 级别失败了。我现在只需要一个简单的加密方法。

注意:忽略安全问题...比如在 js 中公开密钥等。我将在稍后处理这些问题..

4

1 回答 1

1

除非密码始终为 16 字节,否则您不应该在没有填充的情况下使用 AES CBC。它可能会应用某种默认填充,这可能是一个好主意,也可能不是一个好主意。

无论如何:您需要将您的密钥和 iv 作为 WordArray 传递给 CryptoJS;如果你给它一个字符串,它会假设你给它一个密码并从中派生一个不同的密钥。因此,您的 Java 解密代码将使用不同的密钥/iv 对。您可以使用从您的字符串创建一个 WordArray

var key = CryptoJS.enc.Utf8.parse("abcdefghijklmnio")
var iv = ...
于 2014-03-04T13:30:00.303 回答