Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/456.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用Crypto JS解密AES 128-CBC?_Javascript_Encryption_Aes_Cryptojs - Fatal编程技术网

Javascript 如何使用Crypto JS解密AES 128-CBC?

Javascript 如何使用Crypto JS解密AES 128-CBC?,javascript,encryption,aes,cryptojs,Javascript,Encryption,Aes,Cryptojs,我有一个PHP代码,它用一个密钥对有效负载进行解密,我试图使用这个库用JavaScript编写完全相同的代码,但是我得到了错误的结果 有效负载中的前16个字节是向量,其余部分是有用的信息 PHP工作代码- 不工作的JS代码 函数getPayload(){ 常数有效载荷= “ng7W9c9jLhkX7ATMpafNAd5Vt\u skeafaqnquWyquWyquWyquWyquWyquWyquWyquWgWgWgWgWgWg54FjHovejhmvei-G5G8ZnnopifuQQlPCQ8T

我有一个PHP代码,它用一个密钥对有效负载进行解密,我试图使用这个库用JavaScript编写完全相同的代码,但是我得到了错误的结果

有效负载中的前16个字节是向量,其余部分是有用的信息

PHP工作代码-

不工作的JS代码 函数getPayload(){ 常数有效载荷= “ng7W9c9jLhkX7ATMpafNAd5Vt\u skeafaqnquWyquWyquWyquWyquWyquWyquWyquWgWgWgWgWgWg54FjHovejhmvei-G5G8ZnnopifuQQlPCQ8TP2ZFjunsta7VxHmqHnqHnad2Jxaub-VylcjWwzgWgV0WgWgV0V0WgWgWyquzWyqaqaqaquzHbWnWnWnWfzWgWfzWfzWgWgWgWgWgWgWgWgWgWgWgWgWgWg; const key=“zcKf1Zt0UsO43S46Un3pxIgs91R1xMGs”; //获取加密密钥(应用程序客户端密钥的前16个字节) const encryption_key=key.substr(0,16); //解密有效载荷 const base64_original=有效载荷。替换(/-/gi,“+”)。替换(/-/gi,“/”); 常量数据=aes_128_解密(加密密钥,base64_原件); 控制台日志(数据); } 函数aes_128_解密(密码、数据){ const decoded=atob(数据); 设iv=解码的substr(0,16); 让有效载荷=已解码的substr(16); iv=CryptoJS.enc.Hex.parse(iv); const decrypted=CryptoJS.AES.decrypt(有效载荷、密码、{ 四:四,, 填充:CryptoJS.pad.NoPadding }); 返回已解密的.toString(); } window.onload=函数(){ getPayload(); };
JavaScript代码中有几个问题:

  • 密钥不能作为字符串传递,而是作为
    WordArray
    (否则CryptoJS使用密钥派生函数)
  • IV和密文未正确确定
  • 密文必须作为
    CipherParams
    对象(或Base64编码字符串)传递
  • 填充必须是PKCS7(解密也可以使用
    NoPadding
    ,但填充字节不会被删除)
  • 明文必须是Utf8解码(.
    toString()
    hex默认编码)
有关详细信息,请参阅CryptoJS文档,特别是章节和

以下JavaScript代码解密密文:

函数getPayload(){ const payload=“ng7W9c9jLhkX7ATMpafNAd5Vt徖SKEAFAQNQAW1WYQOWB0Q徖CUCS8YQEHEORTDPZWDTNRZHCQ徖UMX7IAAFUPPPGS0ZYDDY7ER1TA05KWGWKHUV54FJHOVEJHOVEI-G5G8ZNOPIFUQQQPCQ8TP2ZFJUNSTA7VXHTMLQNAD2JXAUB-VYLCJWZGV0VACHYYYQQQQQQPMNW6HZWWWW8WWK8WK8WK8WK8WK8WK8WKZWK8WK8WK8WWK8WW; const key=“zcKf1Zt0UsO43S46Un3pxIgs91R1xMGs”; //获取加密密钥(应用程序客户端密钥的前16个字节) //const encryption_key=key.substr(0,16); const encryption_key=CryptoJS.enc.Utf8.parse(key.substr(0,16));//将密钥解析为字数组 //解密有效载荷 const base64_original=有效载荷。替换(/-/gi,“+”)。替换(/-/gi,“/”); 常量数据=aes_128_解密(加密密钥,base64_原件); console.log(data.replace(/(.{56})/g,$1\n');/{“store_id”:20553036,“access_token”:“secret_a9TmTJfRt3gyvxjJ9UwYjs9VQip3F7rp”,“public_token”:“public_qqq99guwvgdvkuzbllynzzdsvxf5if3gh”,“view_mode”:“PAGE”,“lang”:“ru”} //console.log(JSON.parse(data));//将JSON字符串转换为JavaScript对象(可选) } 函数aes_128_解密(密码、数据){ /* const decoded=atob(数据); 设iv=解码的substr(0,16); 让有效载荷=已解码的substr(16); iv=CryptoJS.enc.Hex.parse(iv); */ var ivCiphertext=CryptoJS.enc.Base64.parse(data);//将数据解析为字数组 var iv=CryptoJS.lib.WordArray.create(ivCiphertext.words.slice(0,16/4));//分离iv var payload=CryptoJS.lib.WordArray.create(ivCiphertext.words.slice(16/4));//和ciphertext //const decrypted=CryptoJS.AES.decrypt(有效负载,密码,{ const decrypted=CryptoJS.AES.decrypt( { 密文:有效负载//传递CipherParams对象 }, 密码, { 四:四 //填充:CryptoJS.pad.NoPadding//Apply PKCS7填充 }); //返回已解密的.toString(); 返回解密的.toString(CryptoJS.enc.Utf8);//Utf8解码明文 } window.onload=函数(){ getPayload(); };
非常感谢!我找到了类似的解决方案,请检查!我看不出有多大区别。在您的新代码中,错误也得到了修复。这些差异是微不足道的(例如
atob
/
btoa
vs
Base64
编码器或
Latin1
vs
UTF8
编码器,这与ASCII字符无关)。但是,请注意,您仍在使用
NoPadding
,因此不会删除填充字节。对于当前纯文本,在文本末尾有十个0x0A字节。您可以使用
Hex
编码器而不是
Latin1
。要删除这些填充字节,请使用
Pkcs7
填充(默认设置)。
function getPayload($app_secret_key, $data) {
  // Get the encryption key (16 first bytes of the app's client_secret key)
  $encryption_key = substr($app_secret_key, 0, 16);
 
  // Decrypt payload
  $json_data = aes_128_decrypt($encryption_key, $data);
 
  // Decode json
  $json_decoded = json_decode($json_data, true);
  return $json_data;
}
 
function aes_128_decrypt($key, $data) {
  // Ecwid sends data in url-safe base64. Convert the raw data to the original base64 first
  $base64_original = str_replace(array('-', '_'), array('+', '/'), $data);
 
  // Get binary data
  $decoded = base64_decode($base64_original);
 
  // Initialization vector is the first 16 bytes of the received data
  $iv = substr($decoded, 0, 16);
 
  // The payload itself is is the rest of the received data
  $payload = substr($decoded, 16);
 
  // Decrypt raw binary payload
  $json = openssl_decrypt($payload, "aes-128-cbc", $key, OPENSSL_RAW_DATA, $iv);
  //$json = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $payload, MCRYPT_MODE_CBC, $iv); // You can use this instead of openssl_decrupt, if mcrypt is enabled in your system
 
  return $json;
}
 
// Get payload from the GET and process it
$ecwid_payload = "ng7W9c9jLhkX7ATMpafNAd5Vt_skEaFAqnQaw0Ing1iwYQOwB0Q_CuCS8yQeHeorTdCpZWDTNrzhcq_umX7IaAFUPPgs0zyddY7Er1tA0aze5kWGHUV54fJHoVEJHMmVEi-G5g8ZnNopIFu0YQgQqLpCq8TP2zFJunSTA7VXHTmqHNAD2JXaUb-VylcJWzgV0vaCoGyHqaPbsNNw6HSWkAzhh8dLmsYB0uzsZ_zl3wVXubCL4p2N53PmNPBLCgoC";
$client_secret = "zcKf1Zt0UsO43S46Un3pxIgs91R1xMGs"; 
 
$result = getPayload($client_secret, $ecwid_payload);
 
print($result);