【发布时间】:2021-10-11 04:55:29
【问题描述】:
我在使用 CryptoJS 构建解密函数时遇到问题。
我已经通过函数 create_mpg_aes_encrypt() 创建了一个加密字符串,并尝试构建另一个函数 create_mpg_aes_decrypt() 来解密我生成的字符串。
但是,我无法得到我想要的结果。
另一方面,我构建了一个函数 create_aes_encrypt_try(),以测试 CryptoJS 如何进行解密。我成功地得到了我想要的结果。 但是,根据我的观察,我传递给 CryptoJS.AES.decrypt() 的参数不是字符串,而是数组。
我要构建的函数是用于解密字符串。有什么方法可以解析字符串或者我如何构建这个函数?
//------------------Info--------------------------------------------------------------
let parameter = {
MerchantID: "3430112",
RespondType: "JSON",
TimeStamp: "1485232229",
Version: "1.4",
MerchantOrderNo: "S_1485232229",
Amt: 40,
ItemDesc: "UnitTest",
}
//-------------------Encryption-------------------------------------------------------
const Hashkey = "12345678901234567890123456789012";
const HashIV = "1234567890123456";
const CryptoJS = require('crypto-js');
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 str = create_mpg_aes_encrypt(parameter, key, encrypt_mode);
//console.log(str);
let try_decryption = create_mpg_aes_encrypt_try(parameter, key, encrypt_mode);
let result = create_aes_decrypt(str, key, encrypt_mode);
console.log(result);
//-----------------------------Function-----------------------------------------------
function create_mpg_aes_encrypt(parameter, key, encrypt_mode){
//URL ENCODED QUERY STRING
let params = new URLSearchParams(parameter);
let str = params.toString();
str = addpadding(str);
console.log(str, "\n");
let encrypted_data = CryptoJS.AES.encrypt(str, key, encrypt_mode);
encrypted_data = encrypted_data.ciphertext.toString(CryptoJS.enc.Hex);
str = encrypted_data;
str = str.trim();
return str;
}
function hex2bin (s) {
const ret = []
let i = 0
let l
s += ''
for (l = s.length; i < l; i += 2) {
const c = parseInt(s.substr(i, 1), 16)
const k = parseInt(s.substr(i + 1, 1), 16)
if (isNaN(c) || isNaN(k)) return false
ret.push((c << 4) | k)
}
return String.fromCharCode.apply(String, ret)
}
function addpadding(str){
const blocksize = 32;
let len = str.length;
let pad = blocksize - (len % blocksize);
let string = str;
for(let i = 0; i < pad; i++) {
string += String.fromCharCode(pad);
}
return string;
}
function create_aes_decrypt(tradeinfo, key, encrypt_mode) {
let return_str = "";
let decrypted_data = CryptoJS.AES.decrypt(tradeinfo, key, encrypt_mode);
decrypted_data = decrypted_data.toString();
//console.log(decrypted_data, "\n");
return_str = decrypted_data;
return return_str;
}
function create_mpg_aes_encrypt_try(parameter, key, encrypt_mode){
// URL ENCODED QUERY STRING
let params = new URLSearchParams(parameter);
let str = params.toString();
str = addpadding(str);
let encrypted_data = CryptoJS.AES.encrypt(str, key, encrypt_mode);
let decrypted_data = CryptoJS.AES.decrypt(encrypted_data, key, encrypt_mode);
encrypted_data = encrypted_data.ciphertext.toString(CryptoJS.enc.Hex);
decrypted_data = decrypted_data.toString();
decrypted_data = hex2bin(decrypted_data);
console.log(encrypted_data, "\n");
console.log(decrypted_data, "\n");
str = encrypted_data;
str = str.trim();
return str;
}
// The result I want
/*the string going to be encrypted
MerchantID=3430112&RespondType=JSON&TimeStamp=1485232229&Version=1.4&MerchantOrderNo=S_1485232229&Amt=40&ItemDesc=UnitTest*/
/*the string after encryption
ff91c8aa01379e4de621a44e5f11f72e4d25bdb1a18242db6cef9ef07d80b0165e476fd1d9acaa53170272c82d122961e1a0700a7427cfa1cf90db7f6d6593bbc93102a4d4b9b66d9974c13c31a7ab4bba1d4e0790f0cbbbd7ad64c6d3c8012a601ceaa808bff70f94a8efa5a4f984b9d41304ffd879612177c622f75f4214fa*/
/* After Decryption
MerchantID=3430112&RespondType=JSON&TimeStamp=1485232229&Version=1.4&MerchantOrderNo=S_1485232229&Amt=40&ItemDesc=UnitTest*/
以下是我想实现的php参考代码
function create_aes_decrypt($parameter = "", $key = "", $iv = "") {
return openssl_decrypt(hex2bin($parameter),'AES-256-CBC',
$key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
}
【问题讨论】:
-
只是一般说明:加密适用于二进制数据,而不适用于字符串。如果您的输入是一个字符串(或例如 json-object/string),您需要在加密之前将其转换为二进制形式(例如使用 CryptoJS.enc.Utf8.parse)。加密函数的 输出 不适合常规字符串(想想十六进制 x00),因为很多数据是不可打印的。要获得用于传输或存储的字符串编码,最好在输出上使用 Base64 编码,并在解密之前运行 Base64 解码。有时输出是“十六进制编码字符串” - 然后运行十六进制到二进制转换。
-
@MichaelFehr - 您在哪里确切地看到问题? JavaScript 对象 序列化,密文 十六进制编码,并且将字符串作为纯文本 允许 用于
CryptoJS.AES.encrypt()。但是,它的输出不能简单地用 Base64 或十六进制编码,因为它是一个 JavaScript 对象。 -
@Topaco:我在代码中看不到问题(这就是我写“一般”的原因)。对我来说,看起来 OP 对他自己的函数的不同输入类型有点困惑。
-
@MichaelFehr - 嗯,好的,但有点令人困惑,期待在代码中找到列出的问题之一(不确定我错过了什么),谢谢。
标签: javascript php encryption aes cryptojs