AES / CBC / NoPadding解密中的乱码输出

时间:2014-03-04 12:56:54

标签: java javascript encryption aes cryptojs

我正在尝试解密使用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 

DECRYPT(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中等等。我稍后会处理这些......

1 个答案:

答案 0 :(得分:1)

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

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

从字符串创建WordArray
var key = CryptoJS.enc.Utf8.parse("abcdefghijklmnio")
var iv = ...