使用CryptoJS从解密格式解析为填充最多的字符串时出现问题
我无法让任何东西以我想要的方式使用CryptoJS。我正在尝试用Pksc7填充为AES创建跨语言的可操作性,理想的情况是&;CBC模式。但在这一点上,如果有效的话,我几乎可以接受任何填充物。现在我不确定是我做错了什么,还是我的设置或CryptoJS有问题。我有一个比较大的测试在运行。最后,我需要解密文本的字符串输出,但我得不到。这太令人沮丧了!
我已经在docs上上下下试了很多次,到目前为止尝试了这么多方法,但没有可用的输出,请参阅下面的代码以了解问题。
以下是我查找帮助的一些帖子this和this
我还在我的解析服务器云代码中运行此代码。
上面帖子中的例子可以工作,但不能解码回字符串,而且它只在没有填充的情况下工作-对我来说不行...
任何帮助都会对我的智慧有很大帮助:)
var CryptoJS = require("crypto-js");
const keygen = require('secure-random-password');
/// MY EXAMPLE I WOULD LIKE TO GET WORKING - FROM HERE
var keygenKey = keygen.randomPassword({length: 32, characters: [keygen.lower, keygen.upper, keygen.digits] });
var keygenIV = keygen.randomPassword({length: 16, characters: [keygen.lower, keygen.upper, keygen.digits] });
var key = CryptoJS.enc.Hex.parse("keygenKey");
var iv = CryptoJS.enc.Hex.parse("keygenIV");
var plainText = CryptoJS.enc.Hex.parse("Hello world");
var encrypted = await CryptoJS.AES.encrypt(plainText, key, {
// format: JsonFormatter, // Tried the json formatter from docs - made no difference
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).ciphertext.toString();
var decrypted = await CryptoJS.AES.decrypt({ciphertext: encrypted}, key, {
// format: JsonFormatter, // Tried the json formatter from docs - made no difference
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
/// MY EXAMPLE I WOULD LIKE TO GET WORKING - TO HERE
// Working - but I need padding so this is no good
const examplePlain = CryptoJS.enc.Hex.parse("Hello world");
const exampleKey = CryptoJS.enc.Hex.parse("000102030405060708090a0b0c0d0e0f");
const exampleIV = CryptoJS.enc.Hex.parse("101112131415161718191a1b1c1d1e1f");
const exampleEncrypted = CryptoJS.AES.encrypt(examplePlain, exampleKey, {iv: exampleIV, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.NoPadding}).ciphertext.toString();
const exampleDecrypted = CryptoJS.AES.decrypt({ciphertext: exampleEncrypted}, exampleKey, {iv: exampleIV, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.NoPadding});
var utf8String = decrypted.toString(CryptoJS.enc.Utf8);
var hex = CryptoJS.enc.Hex.stringify(decrypted).toString();
var words = CryptoJS.enc.Utf8.parse(decrypted);
var utf8 = CryptoJS.enc.Utf8.stringify(decrypted);
return {
"keygenIV": keygenIV,
"keygenKey": keygenKey,
"encrypted": encrypted.toString(),
"decrypted": decrypted,
"test_hex": hex,
"test_words": words,
"test_utf8": utf8,
"test_utf8String": utf8String,
"example_encrypted": exampleEncrypted,
"example_decrypted": exampleDecrypted.toString()
}
我要拿回的垃圾
{
keygenIV: 23bfHtf9nmGSXg9G,
keygenKey: B9PFLTwFC87z4WePzkcJLCMNvUnaXinV,
encrypted: 95a3d7b2cd0bf5f35271afa9af359d5e,
decrypted: {words: [487551153, 1344444817, 251806218, 1966320389, 418267123, -2081063279, -2093335598, 1651281808], sigBytes: -112, $super: {}},
test_hex: ,
test_words: {words: [], sigBytes: 0, $super: {}},
test_utf8: ,
test_utf8String: ,
example_encrypted: 0378aaa355b9,
example_decrypted: 417e2f4a1f6192bf7b1a2ab3
}
垃圾信息:
{
keygenIV: 23bfHtf9nmGSXg9G, // Perfect
keygenKey: B9PFLTwFC87z4WePzkcJLCMNvUnaXinV, // Perfect
encrypted: 95a3d7b2cd0bf5f35271afa9af359d5e, //Perfect
// Can't figure out a way to get this object formatted as string
decrypted: {words: [487551153, 1344444817, 251806218, 1966320389, 418267123, -2081063279, -2093335598, 1651281808], sigBytes: -112, $super: {}},
test_hex: ,
test_words: {words: [], sigBytes: 0, $super: {}},
test_utf8: ,
test_utf8String: ,
example_encrypted: 0378aaa355b9, // Whatever...
example_decrypted: 417e2f4a1f6192bf7b1a2ab3 // This does not decode by utf8 I get error: Malformed UTF-8 data
}
解决方案
代码中有一些编码错误:
keygen.randomPassword()
不返回十六进制编码的字符串,但是十六进制编码器用于解析。可以生成十六进制编码的密钥和IV,例如如下所示:var keygenKey = keygen.randomPassword({length: 64, characters: '0123456789abcdef' }); // 32 bytes key var keygenIV = keygen.randomPassword({length: 32, characters: '0123456789abcdef' }); // 16 bytes IV
另外,在分析时,必须删除引号:
var key = CryptoJS.enc.Hex.parse(keygenKey); var iv = CryptoJS.enc.Hex.parse(keygenIV);
请注意,CryptoJS支持生成随机密钥和IV,因此Secure-Random-Password实际上不是必需的:
var key = CryptoJS.lib.WordArray.random(32); var iv = CryptoJS.lib.WordArray.random(16);
明文也使用十六进制编码器进行解析,此处必须应用UTF8编码器:
var plainText = CryptoJS.enc.Utf8.parse("Hello world");
在
decrypt()
调用中,传递的密文是十六进制编码的,而必须传递WordArray
:var decrypted = CryptoJS.AES.decrypt({ciphertext: CryptoJS.enc.Hex.parse(encrypted)},...
通过这些修复,代码可以正常工作:
console.log({
"keygenKey": keygenKey,
"keygenIV": keygenIV,
"encrypted": encrypted,
"decrypted": decrypted.toString(CryptoJS.enc.Utf8),
});
举例说明
{
keygenKey: '10b361a633bfbc163d312d9fd52730d36d19f4db08a7a14481637eaeb662d175',
keygenIV: 'bbfd9b4361a1d6f2bd2a81db1dd7e81b',
encrypted: 'c0771e1f8146ddaf82ea2198e6a2749e',
decrypted: 'Hello world'
}
相关文章