使用 CryptoJS 从解密格式解析为填充最多的字符串时遇到问题
Trouble using CryptoJS parsing from decrypted format to string with most padding
我只是无法使用 CryptoJS 以我想要的方式工作。我正在尝试使用理想的 Pksc7 填充和 CBC 模式为 AES 创建跨语言可操作性。但是在这一点上,如果它有效,我将采用几乎所有填充。现在我不确定是我做错了什么,还是我的设置或 CryptoJS 有问题。我有一个比较大的测试 im 运行。最后,我需要为我的解密文本输出一个字符串,但我没有得到。这非常令人沮丧!
我已经在 docs 上下移动了很多次,到目前为止尝试了很多东西都没有可用的输出,请参阅下面的代码以解决问题。
这是我为了寻求帮助而查看的一些帖子 and this
我也是 运行 我的 Parse 服务器云代码中的这个。
上面帖子中的示例有效但不能解码回字符串,而且它只在没有填充的情况下有效——我不行...
现在任何帮助都会对我的智慧有所帮助:)
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()
不是 return 十六进制编码的字符串,但是十六进制编码器用于解析。可以生成十六进制编码的密钥和 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);
明文也是用hex编码解析的,这里必须使用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'
}
我只是无法使用 CryptoJS 以我想要的方式工作。我正在尝试使用理想的 Pksc7 填充和 CBC 模式为 AES 创建跨语言可操作性。但是在这一点上,如果它有效,我将采用几乎所有填充。现在我不确定是我做错了什么,还是我的设置或 CryptoJS 有问题。我有一个比较大的测试 im 运行。最后,我需要为我的解密文本输出一个字符串,但我没有得到。这非常令人沮丧!
我已经在 docs 上下移动了很多次,到目前为止尝试了很多东西都没有可用的输出,请参阅下面的代码以解决问题。
这是我为了寻求帮助而查看的一些帖子
我也是 运行 我的 Parse 服务器云代码中的这个。
上面帖子中的示例有效但不能解码回字符串,而且它只在没有填充的情况下有效——我不行...
现在任何帮助都会对我的智慧有所帮助:)
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()
不是 return 十六进制编码的字符串,但是十六进制编码器用于解析。可以生成十六进制编码的密钥和 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);
明文也是用hex编码解析的,这里必须使用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'
}