我正在尝试使用谷歌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());
}
}
你知道它为什么会那么糟糕吗?它是一个不同的算法还是我在其他地方失败?
答案 0 :(得分:6)
您在CryptoJS和Java中没有使用相同的密钥和IV。 CryptoJS中的密钥和IV太短而无法生效,因为您将16个字符的字符串解析为Hex,结果只有8个字节,但AES仅支持128,192和256位的密钥大小。
使用
var key = crypto.CryptoJS.enc.Utf8.parse('0123456789012345');
var ive = crypto.CryptoJS.enc.Utf8.parse('0123456789012345');
始终使用随机IV。由于它不必保密,因此您可以将其添加到密文或以其他方式发送。
使用HMAC验证密文或使用GCM等认证模式来防止某些攻击,如填充oracle攻击。
答案 1 :(得分:1)
好的,我发现了问题。 encrypted
我应该通过encrypted.ciphertext
而不是作为参数传递。我现在工作得很完美。