CryptoJS 不忠实地解密非拉丁字符
CryptoJS not decrypting non-Latin characters faithfully
我正在尝试使用 CryptoJS AES,如下所示:
var msg = "café";
var key = "something";
var c = CryptoJS.AES.encrypt(msg, key).toString();
CryptoJS.AES.decrypt(c, key).toString(CryptoJS.enc.Latin1);
很遗憾,这个 returns café
,而不是 café
。显然 Latin1 不是正确的编码,但我找不到更好的编码。有解决办法吗?
谢谢。
您只是缺少格式
正确的方法是使用 CryptoJS.enc.Utf8
所以,请尝试:
CryptoJS.AES.decrypt(c, key).toString(CryptoJS.enc.Utf8);
您正在尝试将您的数据解密为 Latin1 字符串,即使您的输入字符串不是 Latin1 格式。 CryptoJS 内部使用的编码与您用于写入输入文件的编码不同。
加密(字符串-> 字节数组转换)和解密(字节数组-> 字符串转换)都需要指定相同的编码。
https://code.google.com/p/crypto-js/#The_Hasher_Input
The hash algorithms accept either strings or instances of CryptoJS.lib.WordArray [...] an array of 32-bit words. When you pass a string, it's automatically converted to a WordArray encoded as UTF-8.
因此,当您传递一个字符串(并且不使用 CryptoJS.enc.* 生成 WordArray
)时,它会自动将字符串 (message
) 转换为 utf8 WordArray
.
请在此处查看往返示例 encrypt/decrypt:
https://code.google.com/p/crypto-js/#The_Cipher_Output
这是一个与 CryptoJS 一起玩的 jsfiddle
https://jsfiddle.net/8qbf4746/4/
var message = "café";
var key = "something";
var encrypted = CryptoJS.AES.encrypt(message, key);
//equivalent to CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(message), key);
var decrypted = CryptoJS.AES.decrypt(encrypted, key);
$('#1').text("Encrypted: "+encrypted);
$('#2').text("Decrypted: "+decrypted.toString(CryptoJS.enc.Utf8));
为了强调我的观点,使用 Latin1 编码也是一样的:
https://jsfiddle.net/3a8tf48f/2/
var message = "café";
var key = "something";
var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Latin1.parse(message), key);
var decrypted = CryptoJS.AES.decrypt(encrypted, key);
$('#1').text("Encrypted: " + encrypted);
$('#2').text("Decrypted: " + decrypted.toString(CryptoJS.enc.Latin1));
附带说明一下,如果 API 只接受 WordArray
并且不重载 toString 方法(这只是 CryptoJS.enc 的一个方便接口),它可能会更好.*.stringify)。字符串转换魔法有点误导。
我正在尝试使用 CryptoJS AES,如下所示:
var msg = "café";
var key = "something";
var c = CryptoJS.AES.encrypt(msg, key).toString();
CryptoJS.AES.decrypt(c, key).toString(CryptoJS.enc.Latin1);
很遗憾,这个 returns café
,而不是 café
。显然 Latin1 不是正确的编码,但我找不到更好的编码。有解决办法吗?
谢谢。
您只是缺少格式
正确的方法是使用 CryptoJS.enc.Utf8
所以,请尝试:
CryptoJS.AES.decrypt(c, key).toString(CryptoJS.enc.Utf8);
您正在尝试将您的数据解密为 Latin1 字符串,即使您的输入字符串不是 Latin1 格式。 CryptoJS 内部使用的编码与您用于写入输入文件的编码不同。
加密(字符串-> 字节数组转换)和解密(字节数组-> 字符串转换)都需要指定相同的编码。
https://code.google.com/p/crypto-js/#The_Hasher_Input
The hash algorithms accept either strings or instances of CryptoJS.lib.WordArray [...] an array of 32-bit words. When you pass a string, it's automatically converted to a WordArray encoded as UTF-8.
因此,当您传递一个字符串(并且不使用 CryptoJS.enc.* 生成 WordArray
)时,它会自动将字符串 (message
) 转换为 utf8 WordArray
.
请在此处查看往返示例 encrypt/decrypt: https://code.google.com/p/crypto-js/#The_Cipher_Output
这是一个与 CryptoJS 一起玩的 jsfiddle https://jsfiddle.net/8qbf4746/4/
var message = "café";
var key = "something";
var encrypted = CryptoJS.AES.encrypt(message, key);
//equivalent to CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(message), key);
var decrypted = CryptoJS.AES.decrypt(encrypted, key);
$('#1').text("Encrypted: "+encrypted);
$('#2').text("Decrypted: "+decrypted.toString(CryptoJS.enc.Utf8));
为了强调我的观点,使用 Latin1 编码也是一样的: https://jsfiddle.net/3a8tf48f/2/
var message = "café";
var key = "something";
var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Latin1.parse(message), key);
var decrypted = CryptoJS.AES.decrypt(encrypted, key);
$('#1').text("Encrypted: " + encrypted);
$('#2').text("Decrypted: " + decrypted.toString(CryptoJS.enc.Latin1));
附带说明一下,如果 API 只接受 WordArray
并且不重载 toString 方法(这只是 CryptoJS.enc 的一个方便接口),它可能会更好.*.stringify)。字符串转换魔法有点误导。