我正在尝试使用 google 的 https://code.google.com/p/crypto-js/#AES 在 JavaScript 中加密某些内容,就像示例中的那样。问题是我试图用 Java 解密它的结果是完全不同的。我能看到的唯一区别是填充(CryptoJs 使用 Pkcs7,而 java 使用 Pkcs5),阅读了一下后我意识到 Pkcs7 和 Pkcs5 基本相同。
这是我用 Javascript 进行加密的代码示例:
var crypto = require('./aes.js');
var login = 'ABCD';
var key = crypto.CryptoJS.enc.Hex.parse('0123456789012345');
var ive = crypto.CryptoJS.enc.Hex.parse('0123456789012345');
var encrypted = crypto.CryptoJS.AES.encrypt(login, key, {iv: ive});
console.log('encrypted msg = ' + encrypted)
这是我在 Java 中用来解密它的代码:
public String decrypt(byte[] cipherText) throws Exception {
String psk = "0123456789012345";
String iv = "0123456789012345";
try {
String encryptionKey = psk;
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "SunJCE");
final SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes(UTF8), "AES");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv.getBytes(UTF8)));
return new String(cipher.doFinal(cipherText), UTF8);
} catch (BadPaddingException | IllegalBlockSizeException | UnsupportedEncodingException | InvalidAlgorithmParameterException | InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | NoSuchProviderException ex) {
LOG.log(Level.SEVERE, ex.getMessage(), ex);
throw new Exception(ex.getMessage());
}
}
你知道为什么它会失败吗?它是一种不同的算法还是我在其他地方失败了?
最佳答案
您没有在 CryptoJS 和 Java 中使用相同的 key 和 IV。 CryptoJS 中的 key 和 IV 太短而无效,因为您将 16 个字符的字符串解析为十六进制,结果只有 8 个字节,但 AES 仅支持 128、192 和 256 位的 key 大小。
使用
var key = crypto.CryptoJS.enc.Utf8.parse('0123456789012345');
var ive = crypto.CryptoJS.enc.Utf8.parse('0123456789012345');
其他注意事项:
始终使用随机 IV。由于它不必是 secret 的,您可以将它添加到密文之前或以其他方式发送。
使用HMAC对密文进行鉴权,或者使用GCM等鉴权方式,防止padding oracle攻击等攻击。
关于javascript - 使用 CryptoJS 在 Javascript 中加密并在 Java 中解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33223926/