Crypto-js本地端到php服务器端 - javascript

我有一个使用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);

服务器端答案:

3jSTl1yR55lfTbz7f0o3Yw==

我必须错过一些事情,但不能指出。本地无法触及。
欢迎所有帮助

参考方案

如果CryptoJS.AES.encrypt中的第二个参数作为字符串传递,则将其解释为一个密码短语,从该密码短语中导出实际的键和IV,即[1]。这是通过使用OpenSSL函数EVP_BytesToKey的功能(迭代计数为1)和MD5-digest([2] [3])来实现的(请注意,CryptoJS不考虑默认摘要的切换是从从OpenSSL版本1.1.0c开始的MD5到SHA256,[4])。

CryptoJS.AES.encrypt返回一个CipherParams对象,该对象封装了密文,密钥IV和盐[5]。另外,CipherParams#toString()以OpenSSL格式返回结果,作为Base64编码的字符串。 OpenSSL格式由一个16字节的标头和随后的密文组成。标头以ASCII编码的字符串Salted__开头,后跟8字节的盐。每次都会随机生成该盐,并与密码一起使用以导出密钥/ IV。每次创建一个不同的键/ IV。

PHP代码在功能上是相同的:每次使用新生成的盐从口令短语中通过模拟逻辑得出Key和IV(有关证明,请参见下文)。但是,需要进行一些小的更改:

必须删除以下行:$salt ='';
在当前代码中,仅显示Base64编码的密文。对于OpenSSL格式的结果的Base64编码输出,必须改为使用以下代码:

echo base64_encode('Salted__'.$salt.$encrypted_data); 

openssl_encrypt中的第4个参数应从true更改为OPENSSL_RAW_DATA。两者在功能上是相同的,但是OPENSSL_RAW_DATA的使用更加透明。

JavaScript和PHP代码每次都会生成一个新的盐,因此会生成一个不同的密钥和IV,每次都会更改密文。那就是应该的样子。由于盐与密文一起存储,因此可以随时使用密码对密文进行解密。

两种代码使用相同的逻辑来得出密钥和IV的证明:每次生成的新盐/密文都会阻止直接比较两种代码的结果。为了毫不费力地执行此比较,最好也使用PHP代码中JavaScript代码中生成的盐。 JavaScript代码中的salt可通过以下方式确定为十六进制字符串:

console.log(ciphertext.salt.toString(CryptoJS.enc.Hex)); 

此盐将在PHP代码中使用,而不是随机生成的盐(当然,仅用于此比较):

$salt = hex2bin('<Salt from JavaScript-Code as hexadecimal string>'); 

现在比较两个输出可证明它们是相等的,表明两个代码在功能上是相同的。

Javascript IF语句 - javascript

                        嗨,我有这段代码可以正常工作,并将两个日历显示为一个日历。我还有一个php变量$login_session,其中包含登录电子邮件地址的用户。关于如何显示[email protected]日历的任何想法(伪代码)IF $login_session == "[email protected]&#…

提交初始化后删除某些帖子数据 - javascript

在初始化提交之后但在将数据发送到处理页面之前,是否可以过滤$ _POST表单数据?我想象过程的方式:提交->收集$ _POST数据->发送数据我想做的事:提交->收集$ _POST数据->删除某些元素->发送数据这样就不必更改处理页面以过滤掉不希望接收的元素了吗? javascript大神给出的解决方案 当然可以,您可以在JS …

获取JavaScript值到C#字符串 - javascript

                        是否可以在C#中执行类似的操作?该值为“ 10/05/2014”string jsValue = javascript("$('#EstimatedStartDate').val()"); 参考方案 您能否更详细地阐明您要做什么。看来您正在尝试从javascript(客户…

如何使用Javascript将字典列表解析为JSON格式? - javascript

我正在尝试解析JSON格式的词典列表,以便可以使用它们的数据创建一组列表项,其中使用此数据生成文本和ID。我将以下内容传递到我的网页,并在投放之前将其存储在隐藏的div中: [{'text': 'org1', 'id': 'org1ID'}, {'text':…

AES-加密JS和PHP - javascript

我对用cryptojs加密的解密数据有问题。有时它有时不起作用,如果起作用,则返回“消息”,但如果声明,则返回垃圾。 var salt = CryptoJS.lib.WordArray.random(128/8); var key256Bits500Iterations = CryptoJS.PBKDF2("password", salt…