我正在尝试使用共享 key 在 javascript 和 php 之间发送 AES 加密消息。在 Javascript 中,我使用 CryptoJS 库。在 php 中,我使用 mycrypt。我正在尝试在 javascript 中构造一条加密消息,然后使用共享 key 在 php 中对其进行解密。我可以用 JavaScript 加密和解密消息。我可以在 php 中加密和解密相同的消息 - 但两者之间的加密不同。
Javascript
var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase");
alert(encrypted);
给予
U2FsdGVkX18+k3pba4l4MbGZfmDjMc1yQ6uj1fg+BGo=
在 PHP 中
<?php
$Pass = "Secret Passphrase";
$Clear = "Message";
$crypted = fnEncrypt($Clear, $Pass);
echo "Encrypted: ".$crypted."</br>";
$newClear = fnDecrypt($crypted, $Pass);
echo "Decrypted: ".$newClear."</br>";
function fnEncrypt($sValue, $sSecretKey) {
return rtrim(
base64_encode(
mcrypt_encrypt(
MCRYPT_RIJNDAEL_256,
$sSecretKey, $sValue,
MCRYPT_MODE_ECB,
mcrypt_create_iv(
mcrypt_get_iv_size(
MCRYPT_RIJNDAEL_256,
MCRYPT_MODE_ECB
),
MCRYPT_RAND
)
)
),"\0"
);
}
function fnDecrypt($sValue, $sSecretKey) {
return rtrim(
mcrypt_decrypt(
MCRYPT_RIJNDAEL_256,
$sSecretKey,
base64_decode($sValue),
MCRYPT_MODE_ECB,
mcrypt_create_iv(
mcrypt_get_iv_size(
MCRYPT_RIJNDAEL_256,
MCRYPT_MODE_ECB
),
MCRYPT_RAND
)
),"\0"
);
}
输出为
加密:iqJ0R5ahRP7GpWKtW7+OBSCGnudDr99VbJC36OQlmgE=
解密:消息
我的问题是,为什么这些不一样?
最佳答案
如果它们相同,那将是一场密码学灾难......
但是:使用您使用 PHP 加密的方式(使用 EBC 模式),您将始终得到相同的结果。您可以通过查看 http://en.wikipedia.org/wiki/Cipher_block_chaining#Electronic_codebook_.28ECB.29 中的燕尾服图片来了解为什么这是一个问题。
CryptoJS 似乎使用 CBC 作为默认分组密码模式(至少他们在 https://code.google.com/p/crypto-js/#Block_Modes_and_Padding 中这么说),它具有随机初始向量。这比 CBC 更好。
如果您使用相同的密码、相同的分组密码模式(例如 CBC)以及相同的 key 和 IV - 当然还有相同的明文 - 注释表明也可能存在 unicode,结果应该是相同的问题。
此外,MCRYPT_RIJNDAEL_256 不是 AES。 AES 的 block 大小为 16 字节 - AES-128 的 key 大小为 16 字节,AES-256 的 key 大小为 32 字节。 MCRYPT_RIJNDAEL_256 的 block 大小为 32 字节 - 这是一个很大的差异。
最后一点:仅加密数据是不够的!您还必须通过使用 HMAC 或使用经过身份验证的 block 密码模式(如 GCM)对其进行身份验证 - 如果您不这样做,您可能至少容易受到填充预言机攻击:http://en.wikipedia.org/wiki/Padding_oracle_attack
关于javascript - 使用 CryptoJS 在 JavaScript 中进行 AES 加密/解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21804911/