Node.js中的crypto模块与AES256解密中的CryptoJS的区别
The difference between crypto module in Node.js and CryptoJS in AES256 decryption
我目前正在尝试将使用 CryptoJS 的解密代码转换为使用 node.js 中的加密模块的方法。
我猜他们的填充设置有一些差异导致我的代码出错。
以下部分是我使用加密模块的代码:
// Decrypt Info
let data = "27e25136f89a4d75f41a2448b1dc4fbea38784d4087b22e1ee271872ae214c684c058746c336cd43fd2d65d7df12efa742567943d8d2e51301c8bfb04d070e8888198027c463c6beec419ad06aeeeeedbd49ce33902994e3218e2b9d1b15b34eb7111f803b110361172a5403fcb7fc98cec59be0fb13d74f10bc87d7a72cd29ada7853ac2208c0c5cff840b37fffd91d82e1d7dd9ed8f73735dc47a9bbfd3b95ef2d1f52fb77168baa7d80f25126b4cda163b1323f8070cad860bf1e1bf22810654d2a0d2962fcdd5fa4106ebc9b09a3cbc5488bea145fbb363f8fd44638716c1632a9885efd57dc344fa3e1e1a26fc0133ebb84b49628bfc210197b545d4922ebdbdeded1c64718351499486ea2a0a26bd2cf8e11c6cdea92878c91b8d4f38669ff2255b1d6f7a292f2b5a72fd4bc6e7acc582896407acc77e738c316979c350e2e7d5c20bc7e5924cd9fbec9259c2b58da04900ed7d2ffe71e6807aa789e20156110eac470bfc46a91de4b6507d728ca7fb1addf3abe22b6a71e95aca90ca710788676f36774744cac19033625d427b81fc64b80c49b9f16207c550736a04a2d0aef6a76aaeeeb1b0168db31c51ad3e62bfdcd0640e40346135e50aa68c113c03dc4a41d9688e3220a4b89bdf67b8a710dbe00b62321ac98f865d59e77f41d";
let tradeinfo = data; // Get result from Bubble
const Hashkey = "9P32kffvsqoraSlBhyluMN9U90DvXp9e";
const HashIV = "CItKoTyaRbHhSAEP";
//-------------------Encryption------------------------------------
var crypto = require('crypto');
const algorithm = "aes-256-cbc";
//-------------------Main------------------------------------------
let f_result = create_aes_decrypt(tradeinfo, Hashkey, HashIV, algorithm);
console.log(f_result);
//-------------------Function--------------------------------------
function create_aes_decrypt(tradeinfo, key, iv, algorithm) {
let return_str = "";
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted_data = decipher.update(tradeinfo, "hex", "utf-8");
decrypted_data += decipher.final("utf-8");
return_str = strippadding(decrypted_data);
return return_str;
}
function strippadding(str) {
let len = str.length
let slast = my_substr_short(str, -1); // use my_substr_short to replace substr in php
slast = ord(slast);
slastc = String.fromCharCode(slast);
let re = slastc + "{" + slast + "}";
//console.log(my_preg_match(re, str));
if(my_preg_match(re, str)){
str = my_substr_full(str, 0, len - slast);
return str;
}
else
return false;
}
function my_substr_short(str, len2get) {
let len = str.length;
let return_str = "";
if(len2get >= 0) {
for(let i = 0; i < len2get; i++)
return_str += str[i];
}
else {
len2get = -len2get;
if (len2get > len)
len2get = len;
for(let i = 0; i < len2get; i++)
return_str += str[(len - len2get) + i];
}
return return_str;
}
function my_substr_full(str, start, len2get) {
let len = str.length;
let return_str = "";
for(let i = start; i < len2get; i++)
return_str += str[i];
return return_str;
}
function ord(str){
return str.charCodeAt(0);
}
function my_preg_match(pattern, str) {
if(str.match(pattern) != null)
return true;
else
return false;
}
这是我在加密模块代码中收到的错误消息:Error: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
下面的部分是使用CryptoJS的代码,我可以成功得到我预期的结果。
// Decrypt Info
let data = "27e25136f89a4d75f41a2448b1dc4fbea38784d4087b22e1ee271872ae214c684c058746c336cd43fd2d65d7df12efa742567943d8d2e51301c8bfb04d070e8888198027c463c6beec419ad06aeeeeedbd49ce33902994e3218e2b9d1b15b34eb7111f803b110361172a5403fcb7fc98cec59be0fb13d74f10bc87d7a72cd29ada7853ac2208c0c5cff840b37fffd91d82e1d7dd9ed8f73735dc47a9bbfd3b95ef2d1f52fb77168baa7d80f25126b4cda163b1323f8070cad860bf1e1bf22810654d2a0d2962fcdd5fa4106ebc9b09a3cbc5488bea145fbb363f8fd44638716c1632a9885efd57dc344fa3e1e1a26fc0133ebb84b49628bfc210197b545d4922ebdbdeded1c64718351499486ea2a0a26bd2cf8e11c6cdea92878c91b8d4f38669ff2255b1d6f7a292f2b5a72fd4bc6e7acc582896407acc77e738c316979c350e2e7d5c20bc7e5924cd9fbec9259c2b58da04900ed7d2ffe71e6807aa789e20156110eac470bfc46a91de4b6507d728ca7fb1addf3abe22b6a71e95aca90ca710788676f36774744cac19033625d427b81fc64b80c49b9f16207c550736a04a2d0aef6a76aaeeeb1b0168db31c51ad3e62bfdcd0640e40346135e50aa68c113c03dc4a41d9688e3220a4b89bdf67b8a710dbe00b62321ac98f865d59e77f41d";
let tradeinfo = data; // Get result from Bubble
const CryptoJS = require('crypto-js');
const Hashkey = "9P32kffvsqoraSlBhyluMN9U90DvXp9e";
const HashIV = "CItKoTyaRbHhSAEP";
//-------------------Encryption------------------------------------
const key = CryptoJS.enc.Utf8.parse(Hashkey);
const iv = CryptoJS.enc.Utf8.parse(HashIV);
const encrypt_mode = {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.ZeroPadding
};
//-------------------Main------------------------------------------
let f_result = create_aes_decrypt(tradeinfo, key, encrypt_mode);
console.log(f_result);
//-------------------Function--------------------------------------
function create_aes_decrypt(tradeinfo, key, encrypt_mode) {
let return_str = "";
let decrypted_data = CryptoJS.AES.decrypt({ciphertext: CryptoJS.enc.Hex.parse(tradeinfo)}, key, encrypt_mode);
decrypted_data = decrypted_data.toString(CryptoJS.enc.Utf8);
return_str = strippadding(decrypted_data);
return return_str;
}
function strippadding(str) {
let len = str.length
let slast = my_substr_short(str, -1); // use my_substr_short to replace substr in php
slast = ord(slast);
slastc = String.fromCharCode(slast);
let re = slastc + "{" + slast + "}";
//console.log(my_preg_match(re, str));
if(my_preg_match(re, str)){
str = my_substr_full(str, 0, len - slast);
return str;
}
else
return false;
}
function my_substr_short(str, len2get) {
let len = str.length;
let return_str = "";
if(len2get >= 0) {
for(let i = 0; i < len2get; i++)
return_str += str[i];
}
else {
len2get = -len2get;
if (len2get > len)
len2get = len;
for(let i = 0; i < len2get; i++)
return_str += str[(len - len2get) + i];
}
return return_str;
}
function my_substr_full(str, start, len2get) {
let len = str.length;
let return_str = "";
for(let i = start; i < len2get; i++)
return_str += str[i];
return return_str;
}
function ord(str){
return str.charCodeAt(0);
}
function my_preg_match(pattern, str) {
if(str.match(pattern) != null)
return true;
else
return false;
}
导致此问题的原因是加密模块和 CryptoJS 之间的填充或编码差异吗?
下面的部分是我期望得到的结果。
{"Status":"SUCCESS","Message":"\u6388\u6b0a\u6210\u529f","Result":{"MerchantID":"MS121595179","Amt":400,"TradeNo":"21082522362641751","MerchantOrderNo":"1629902168","RespondType":"JSON","IP":"140.114.214.77","EscrowBank":"HNCB","PaymentType":"CREDIT","RespondCode":"00","Auth":"607048","Card6No":"400022","Card4No":"1111","Exp":"2606","TokenUseStatus":"0","InstFirst":0,"InstEach":0,"Inst":0,"ECI":"","PayTime":"2021-08-25 22:36:26","PaymentMethod":"CREDIT"}}
由于您使用的是自定义填充,因此您需要禁用默认的 PKCS#7 填充:
decipher.setAutoPadding(false);
此调用必须在 update()
和 final()
调用之前完成。
我目前正在尝试将使用 CryptoJS 的解密代码转换为使用 node.js 中的加密模块的方法。 我猜他们的填充设置有一些差异导致我的代码出错。
以下部分是我使用加密模块的代码:
// Decrypt Info
let data = "27e25136f89a4d75f41a2448b1dc4fbea38784d4087b22e1ee271872ae214c684c058746c336cd43fd2d65d7df12efa742567943d8d2e51301c8bfb04d070e8888198027c463c6beec419ad06aeeeeedbd49ce33902994e3218e2b9d1b15b34eb7111f803b110361172a5403fcb7fc98cec59be0fb13d74f10bc87d7a72cd29ada7853ac2208c0c5cff840b37fffd91d82e1d7dd9ed8f73735dc47a9bbfd3b95ef2d1f52fb77168baa7d80f25126b4cda163b1323f8070cad860bf1e1bf22810654d2a0d2962fcdd5fa4106ebc9b09a3cbc5488bea145fbb363f8fd44638716c1632a9885efd57dc344fa3e1e1a26fc0133ebb84b49628bfc210197b545d4922ebdbdeded1c64718351499486ea2a0a26bd2cf8e11c6cdea92878c91b8d4f38669ff2255b1d6f7a292f2b5a72fd4bc6e7acc582896407acc77e738c316979c350e2e7d5c20bc7e5924cd9fbec9259c2b58da04900ed7d2ffe71e6807aa789e20156110eac470bfc46a91de4b6507d728ca7fb1addf3abe22b6a71e95aca90ca710788676f36774744cac19033625d427b81fc64b80c49b9f16207c550736a04a2d0aef6a76aaeeeb1b0168db31c51ad3e62bfdcd0640e40346135e50aa68c113c03dc4a41d9688e3220a4b89bdf67b8a710dbe00b62321ac98f865d59e77f41d";
let tradeinfo = data; // Get result from Bubble
const Hashkey = "9P32kffvsqoraSlBhyluMN9U90DvXp9e";
const HashIV = "CItKoTyaRbHhSAEP";
//-------------------Encryption------------------------------------
var crypto = require('crypto');
const algorithm = "aes-256-cbc";
//-------------------Main------------------------------------------
let f_result = create_aes_decrypt(tradeinfo, Hashkey, HashIV, algorithm);
console.log(f_result);
//-------------------Function--------------------------------------
function create_aes_decrypt(tradeinfo, key, iv, algorithm) {
let return_str = "";
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted_data = decipher.update(tradeinfo, "hex", "utf-8");
decrypted_data += decipher.final("utf-8");
return_str = strippadding(decrypted_data);
return return_str;
}
function strippadding(str) {
let len = str.length
let slast = my_substr_short(str, -1); // use my_substr_short to replace substr in php
slast = ord(slast);
slastc = String.fromCharCode(slast);
let re = slastc + "{" + slast + "}";
//console.log(my_preg_match(re, str));
if(my_preg_match(re, str)){
str = my_substr_full(str, 0, len - slast);
return str;
}
else
return false;
}
function my_substr_short(str, len2get) {
let len = str.length;
let return_str = "";
if(len2get >= 0) {
for(let i = 0; i < len2get; i++)
return_str += str[i];
}
else {
len2get = -len2get;
if (len2get > len)
len2get = len;
for(let i = 0; i < len2get; i++)
return_str += str[(len - len2get) + i];
}
return return_str;
}
function my_substr_full(str, start, len2get) {
let len = str.length;
let return_str = "";
for(let i = start; i < len2get; i++)
return_str += str[i];
return return_str;
}
function ord(str){
return str.charCodeAt(0);
}
function my_preg_match(pattern, str) {
if(str.match(pattern) != null)
return true;
else
return false;
}
这是我在加密模块代码中收到的错误消息:Error: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
下面的部分是使用CryptoJS的代码,我可以成功得到我预期的结果。
// Decrypt Info
let data = "27e25136f89a4d75f41a2448b1dc4fbea38784d4087b22e1ee271872ae214c684c058746c336cd43fd2d65d7df12efa742567943d8d2e51301c8bfb04d070e8888198027c463c6beec419ad06aeeeeedbd49ce33902994e3218e2b9d1b15b34eb7111f803b110361172a5403fcb7fc98cec59be0fb13d74f10bc87d7a72cd29ada7853ac2208c0c5cff840b37fffd91d82e1d7dd9ed8f73735dc47a9bbfd3b95ef2d1f52fb77168baa7d80f25126b4cda163b1323f8070cad860bf1e1bf22810654d2a0d2962fcdd5fa4106ebc9b09a3cbc5488bea145fbb363f8fd44638716c1632a9885efd57dc344fa3e1e1a26fc0133ebb84b49628bfc210197b545d4922ebdbdeded1c64718351499486ea2a0a26bd2cf8e11c6cdea92878c91b8d4f38669ff2255b1d6f7a292f2b5a72fd4bc6e7acc582896407acc77e738c316979c350e2e7d5c20bc7e5924cd9fbec9259c2b58da04900ed7d2ffe71e6807aa789e20156110eac470bfc46a91de4b6507d728ca7fb1addf3abe22b6a71e95aca90ca710788676f36774744cac19033625d427b81fc64b80c49b9f16207c550736a04a2d0aef6a76aaeeeb1b0168db31c51ad3e62bfdcd0640e40346135e50aa68c113c03dc4a41d9688e3220a4b89bdf67b8a710dbe00b62321ac98f865d59e77f41d";
let tradeinfo = data; // Get result from Bubble
const CryptoJS = require('crypto-js');
const Hashkey = "9P32kffvsqoraSlBhyluMN9U90DvXp9e";
const HashIV = "CItKoTyaRbHhSAEP";
//-------------------Encryption------------------------------------
const key = CryptoJS.enc.Utf8.parse(Hashkey);
const iv = CryptoJS.enc.Utf8.parse(HashIV);
const encrypt_mode = {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.ZeroPadding
};
//-------------------Main------------------------------------------
let f_result = create_aes_decrypt(tradeinfo, key, encrypt_mode);
console.log(f_result);
//-------------------Function--------------------------------------
function create_aes_decrypt(tradeinfo, key, encrypt_mode) {
let return_str = "";
let decrypted_data = CryptoJS.AES.decrypt({ciphertext: CryptoJS.enc.Hex.parse(tradeinfo)}, key, encrypt_mode);
decrypted_data = decrypted_data.toString(CryptoJS.enc.Utf8);
return_str = strippadding(decrypted_data);
return return_str;
}
function strippadding(str) {
let len = str.length
let slast = my_substr_short(str, -1); // use my_substr_short to replace substr in php
slast = ord(slast);
slastc = String.fromCharCode(slast);
let re = slastc + "{" + slast + "}";
//console.log(my_preg_match(re, str));
if(my_preg_match(re, str)){
str = my_substr_full(str, 0, len - slast);
return str;
}
else
return false;
}
function my_substr_short(str, len2get) {
let len = str.length;
let return_str = "";
if(len2get >= 0) {
for(let i = 0; i < len2get; i++)
return_str += str[i];
}
else {
len2get = -len2get;
if (len2get > len)
len2get = len;
for(let i = 0; i < len2get; i++)
return_str += str[(len - len2get) + i];
}
return return_str;
}
function my_substr_full(str, start, len2get) {
let len = str.length;
let return_str = "";
for(let i = start; i < len2get; i++)
return_str += str[i];
return return_str;
}
function ord(str){
return str.charCodeAt(0);
}
function my_preg_match(pattern, str) {
if(str.match(pattern) != null)
return true;
else
return false;
}
导致此问题的原因是加密模块和 CryptoJS 之间的填充或编码差异吗?
下面的部分是我期望得到的结果。
{"Status":"SUCCESS","Message":"\u6388\u6b0a\u6210\u529f","Result":{"MerchantID":"MS121595179","Amt":400,"TradeNo":"21082522362641751","MerchantOrderNo":"1629902168","RespondType":"JSON","IP":"140.114.214.77","EscrowBank":"HNCB","PaymentType":"CREDIT","RespondCode":"00","Auth":"607048","Card6No":"400022","Card4No":"1111","Exp":"2606","TokenUseStatus":"0","InstFirst":0,"InstEach":0,"Inst":0,"ECI":"","PayTime":"2021-08-25 22:36:26","PaymentMethod":"CREDIT"}}
由于您使用的是自定义填充,因此您需要禁用默认的 PKCS#7 填充:
decipher.setAutoPadding(false);
此调用必须在 update()
和 final()
调用之前完成。