我正在用Java加密一个文件,需要在客户端解密它。这是服务器端的代码:
Key secretKey = new SecretKeySpec("mysecretmysecret".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] outputBytes = cipher.doFinal(read(sampleFile));
return outputBytes;在客户端,我使用Ajax请求获取文件并使用CryptoJS AES:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'file', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function (e) {
var encryptedData = this.response;
var decrypted = CryptoJS.AES.decrypt(encryptedData, "mysecretmysecret");
console.log(decrypted);
};
xhr.send();但这并不能解密文件。我在控制台中将此打印为解密值:
W…y.init {words: Array[0], sigBytes: 0}我还尝试将arraybuffer转换为WordArray,建议使用这里,但结果仍然相同。如果有人能指出我的正确方向,告诉我我做错了什么,我会非常高兴的。
编辑1:我已经解决了这个问题。我使用的代码是作为答案发布的。
发布于 2016-04-25 15:13:53
让我们回顾一下,在Java中,您正在使用
如果密钥作为字符串传递给CryptoJS,则必须使用OpenSSL的EVP_BytesToKey和一轮MD5从假定的密码中派生密钥。因为您的密文不是用OpenSSL兼容的格式编码的,所以它将失败。问题是你不需要那个。
下面的代码将正确地解密来自Java的密文,但并不十分安全:
var passwordWords = CryptoJS.enc.Utf8.parse("mysecretmysecret");
var decrypted = CryptoJS.AES.decrypt({
ciphertext: CryptoJS.lib.WordArray.create(encryptedData) // or use some encoding
}, passwordWords, {
mode: CryptoJS.mode.ECB
});
console.log(decrypted.toString(CryptoJS.enc.Utf8)); // in case the plaintext is text欧洲央行模式不包括在基本汇总中,因此您必须在主JavaScript文件文件之后的页面中包含该CryptoJS。
而且,默认情况下,CryptoJS不处理ArrayBuffer。为此您需要包含希姆 (源:这个答案)。
这方面的问题在于其不安全。欧洲央行的模式非常不安全。
发布于 2016-04-26 09:22:17
所以我终于解决了这个问题。感谢Artjom指出了正确的方向。我已经将我的Java代码更改为在PKCS5Padding中使用CBC。
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec myKey = new SecretKeySpec("mysecretmysecret".getBytes(), "AES");
IvParameterSpec IVKey = new IvParameterSpec("mysecretmysecret".getBytes());
cipher.init(Cipher.ENCRYPT_MODE, myKey, IVKey);
byte[] outputBytes = cipher.doFinal(read(sampleFile));
return outputBytes;我的javascript是这样的:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'file', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
var encryptedData = this.response;
var passwordWords = CryptoJS.enc.Utf8.parse("mysecretmysecret"); //yes I know, not a big secret!
var wordArray = CryptoJS.lib.WordArray.create(encryptedData);
var decrypted = CryptoJS.AES.decrypt({
ciphertext: wordArray
}, passwordWords, {
iv: passwordWords, //yes I used password as iv too. Dont mind.
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log(decrypted); //Eureka!!
};
xhr.send();decrypted是WordArray。
https://stackoverflow.com/questions/36839254
复制相似问题