java加密aes值和javascript加密值不匹配
我有java代码,它为我产生aes加密代码,现在我正尝试在javascript上使用crypto-js,但两种代码都提供了不同的密钥,我不知道为什么以及如何在这里得到同样关键的是我的代码java加密aes值和javascript加密值不匹配
public static String encrypt(String text, byte[] iv, byte[] key)throws Exception{
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
System.out.println("KEY SPECCCC: "+keySpec);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE,keySpec,ivSpec);
byte [] results = cipher.doFinal(text.getBytes("UTF-8"));
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(results);
}
JavaScript代码
require(["crypto-js/core", "crypto-js/aes"], function (CryptoJS, AES) {
ciphertext = CryptoJS.AES.encrypt(JSON.stringify(jsondata),
arr.toString(),arr.toString());
});
字符串为UTF-8
var utf8 = unescape(encodeURIComponent(key));
var arr = [];
for (var i = 0; i < utf8.length; i++) {
arr.push(utf8.charCodeAt(i));
}
首先,即使您的代码难以正常工作,您也无法正确解密它,因为在Java中创建AES密码时,您使用的是CBC密码,而您正在实现PKCS5Padding的填充算法。 所以你的java代码做到以下几点: 当它得到输入时,它首先将它分成16位块,然后如果你的输入没有分成16个整体,那么提醒将被填充以用相同数量的提醒填充块。你可以看到我的意思是以下图片。
所以它会做与Java端填充密码,但在JavaScript部分,您加密既不宣布将使用什么类型的模式AES,也不宣布它该做的是什么类型的填充。因此,您应该将这些值添加到您的代码中。您可以搜索以下代码部分。
mode:CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
关于不同的密钥,因为您要发送的字节[]到你的加密方法,然后用这个未知的字节[],而你正在创建Key.You didnt提到它正在发生,为什么你的加密方法在你的程序中使用,但你应该在两个方法中创建“Byte []键”。例如,你可以参考下面的代码作为生成的例子,但它不是生成密钥的安全方式,我只是将它添加为告诉你我的意思是你应该以同样的方式生成两个键。
//DONT USE THIS IMPLEMENTATION SINCE IT IS NOT SAFE!
byte[] key = (username + password).getBytes("UTF-8");
默认情况下,CryptoJS使用CBC模式和PKCS#7填充。问题在于“密钥”可能是CryptoJS将其视为密码并从中导出密钥的字符串。 –
Java代码生成一个加密的字符串,并为JavaScript生成相同的加密字符串,下面的代码工程!
var IVstring = CryptoJS.lib.ByteArray(your IV bytearray).toString(CryptoJS.enc.Base64);
var keystring = CryptoJS.lib.ByteArray(your KEY bytearray).toString(CryptoJS.enc.Base64);
var text = 'texttobeencrypted';
var key = CryptoJS.enc.Base64.parse(keystring);
var iv = CryptoJS.enc.Base64.parse(IVstring);
var encrypted = CryptoJS.AES.encrypt(text, key, {iv: iv});
console.log(encrypted.toString());
脚本链接: 添加CryptJS,AES和 https://greasyfork.org/scripts/6696-cryptojs-lib-bytearray/code/CryptoJSlibByteArray.js
如果您只使用对称加密,你需要在服务器和客户端完全相同的关键。如果您将加密密钥从服务器发送到客户端或其他方式需要加密对称加密密钥。最简单的方法是使用TLS。如果你使用TLS,那么数据和密钥都是加密的,所以你不需要自己加密。这不提供任何安全性,只是一点混淆。您应该阅读:https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/ –
您的代码不完整。你能证明你如何解码Java和JS中的密钥和IV以及实际值? –
IV必须是不可预知的(阅读:随机)。不要使用静态IV或与密钥相同的值,因为这会使密码具有确定性,因此不会在语义上安全。观察密文的攻击者可以确定何时之前发送了相同的消息前缀。 IV不是秘密的,所以你可以把它和密文一起发送。通常,它只是在密文前面加上,然后在解密之前切掉。 –