Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/404.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 加密js本地端到php服务器端_Javascript_Php_Cryptography_Aes - Fatal编程技术网

Javascript 加密js本地端到php服务器端

Javascript 加密js本地端到php服务器端,javascript,php,cryptography,aes,Javascript,Php,Cryptography,Aes,我有一个使用crypto Js AES的应用程序。模拟工作代码为: var ciphertext = CryptoJS.AES.encrypt('My_message', 'My_secret_key'); console.log(ciphertext.toString()); 答案是: U2FsdGVkX1/Dd3uAr/mdw5lVoBvq0UX5LHnNoX24JAM= 当我尝试在服务器端复制时,我从未得到相同的答案: $passphrase='My_secret_key'; $va

我有一个使用crypto Js AES的应用程序。模拟工作代码为:

var ciphertext = CryptoJS.AES.encrypt('My_message', 'My_secret_key');
console.log(ciphertext.toString()); 
答案是:

U2FsdGVkX1/Dd3uAr/mdw5lVoBvq0UX5LHnNoX24JAM=
当我尝试在服务器端复制时,我从未得到相同的答案:

$passphrase='My_secret_key';
$value='My_message';
$salt = openssl_random_pseudo_bytes(8);
$salt ='';
$salted = '';
$dx = '';
while (strlen($salted) < 48) {
 $dx = md5($dx.$passphrase.$salt, true);
 $salted .= $dx;
}
$key = substr($salted, 0, 32);
$iv  = substr($salted, 32,16);
$encrypted_data = openssl_encrypt($value, 'aes-256-cbc', $key, true, $iv);
echo base64_encode($encrypted_data);
我肯定错过了什么,但我不能指出什么。当地人不能碰。
欢迎提供一切帮助

我以前就遇到过你这种情况。我们很难在PHP和Java(Android)上获得相同的结果。许多开发人员在2家公司工作了很多天。不走运

我们最终从PHP调用了CryptoJS。如果我没记错的话,Crypto JS中有一些非标准的东西。我可能错了,那是很久以前的事了

通过PHP使用node调用CryptoJS可能是一个更健壮的解决方案。然后您可以使用相同的库来确保兼容性

$result = shell_exec('node yourCryptoJSprogram.js');
我们确实达到了以这种方式作为参数传递的数据量的限制。我建议使用PHP编写文件,然后再次使用NodeJS读取

如果性能出现问题,请考虑运行一个Express服务器并从PHP中进行REST调用。< /P>

如果这个答案不满足你,考虑使用或复制这个简单的基于OpenSSL的PHP库,我写了出来想出来:


如果
CryptoJS.AES.encrypt
中的第二个参数作为字符串传递,则它将被解释为一个密码短语,实际密钥和IV是从该密码短语派生的。这是通过使用OpenSSL函数<代码> EVPyByTestKEY < /代码>的功能实现的,其迭代计数为“代码>1 < /COD>”和MD5摘要(注意,CryptoJS不考虑默认摘要从MD5到SU256从OpenSSL版本1.1.0C on)的切换。p>
CryptoJS.AES.encrypt
返回一个
CipherParams
-对象,该对象封装密文、密钥、IV和salt。此外,
CipherParams#toString()
以OpenSSL格式将结果返回为Base64编码字符串。OpenSSL格式由一个16字节的头和随后的密文组成。标头以ASCII编码的字符串
Salted__
开头,后跟一个8字节的salt。salt每次随机生成,并与密码一起用于派生密钥/IV。这每次都会创建不同的密钥/IV

PHP代码在功能上是相同的:Key和IV每次都使用新生成的salt从密码短语中使用模拟逻辑派生(有关证明,请参见下文)。但是,有必要进行一些小改动:

  • 必须删除以下行:
    $salt=''

  • 在当前代码中,仅显示Base64编码的密文。对于OpenSSL格式的结果的Base64编码输出,代码必须改为:

    echo base64_encode('Salted__'.$salt.$encrypted_data); 
    
  • openssl\u encrypt
    中的第四个参数应该从
    true
    更改为
    openssl\u RAW\u DATA
    。两者在功能上是相同的,但是使用
    OPENSSL\u原始\u数据
    更加透明

JavaScript和PHP代码每次生成一个新的salt,从而生成一个不同的键和IV,每次都会更改密文。应该是这样的。由于salt与密文一起存储,因此可以随时使用密码短语对密文进行解密

证明两个代码使用相同的逻辑来推导key和IV:每次生成的新salt/密文阻止了对两个代码的结果进行直接比较。为了不费吹灰之力地进行比较,最好在PHP代码中也使用JavaScript代码中生成的salt。JavaScript代码中的salt可以确定为十六进制字符串,带有:

console.log(ciphertext.salt.toString(CryptoJS.enc.Hex)); 
此salt将用于PHP代码中,而不是随机生成的salt(当然,仅用于这一比较):

$salt=hex2bin(“”);
现在,对两个输出的比较证明它们是相等的,这表明两个代码在功能上是相同的。

通过PHP使用node调用CryptoJS可能是一个更健壮的解决方案。-真的不是!我给未来读者的建议是不要使用CryptoJS——它有糟糕的文档,并且隐藏了许多导致类似问题的重要实现细节。
console.log(ciphertext.salt.toString(CryptoJS.enc.Hex)); 
$salt = hex2bin('<Salt from JavaScript-Code as hexadecimal string>');