AES CryptoJS加密和phpseclib解密
AES CryptoJS encryption and phpseclib decryption
我有下一个问题
Node.js 我有下一个代码
var iv = CryptoJS.enc.Hex.parse('00000000000000000000000000000000'); //it's for tests, later it will be dynamically generated
var key256Bits = 'A5178B6A965AACF3CD60B07A15061719';
var cipher = CryptoJS.AES.encrypt(
'Some text',
key256Bits,
{
iv: iv,
padding:CryptoJS.pad.ZeroPadding
}
).toString();
然后当我尝试用 phpseclib 解码它时
$key = 'A5178B6A965AACF3CD60B07A15061719';
$data = /*text encrypted by JS*/;
$cipher = new AES();
$cipher->setKeyLength(256);
$cipher->setKey($key);
$res = $cipher->decrypt($data);
然后$res变成空串
我做错了什么?
如果您将字符串作为密钥传递给 CryptoJS.<cipher>.encrypt
,CryptoJS 会将其视为密码,并将使用带有随机盐的 OpenSSL EVP_BytesToKey
和一次迭代从中派生出实际密钥MD5。
phpseclib 没有它的实现,所以你可以传入实际的密钥:
var key256Bits = CryptoJS.enc.Utf8.parse('A5178B6A965AACF3CD60B07A15061719');
由于这个密钥只有32个hexits长,它只有128位的熵,但仍然使用AES-256。您需要 64 个十六进制,您可以在使用前对其进行解码以获得 32 个字节的安全密钥大小。
此外,phpseclib 实现了 PKCS#7 填充,因此您需要使用
padding: CryptoJS.pad.Pkcs7
在 CryptoJS 中。
示例 JavaScript 代码:
var iv = CryptoJS.enc.Hex.parse('00000000000000000000000000000000'); //it's for tests, later it will be dynamically generated
var key256Bits = CryptoJS.enc.Utf8.parse('A5178B6A965AACF3CD60B07A15061719');
var cipher = CryptoJS.AES.encrypt(
'Some text',
key256Bits,
{
iv: iv,
padding: CryptoJS.pad.Pkcs7
}
).toString();
console.log(cipher)
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/aes.js"></script>
在PHP中,使用前需要确保解密密文:
$data = base64_decode("IWkBG3A46rNrxwWN2JD7xQ==");
$key = 'A5178B6A965AACF3CD60B07A15061719';
$cipher = new AES();
$cipher->setKeyLength(256);
$cipher->setKey($key);
$res = $cipher->decrypt($data);
var_dump($res);
安全考虑:
如果您只使用对称加密,您需要在服务器和客户端使用完全相同的密钥。如果您将加密密钥从服务器发送到客户端或以其他方式发送,您需要加密您的对称加密密钥。最简单的方法是使用 TLS。如果您使用 TLS,那么数据和密钥都会被加密,因此您不需要自己加密。这不提供任何安全性,只是有点混淆。你应该阅读:https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/
我有下一个问题
Node.js 我有下一个代码
var iv = CryptoJS.enc.Hex.parse('00000000000000000000000000000000'); //it's for tests, later it will be dynamically generated
var key256Bits = 'A5178B6A965AACF3CD60B07A15061719';
var cipher = CryptoJS.AES.encrypt(
'Some text',
key256Bits,
{
iv: iv,
padding:CryptoJS.pad.ZeroPadding
}
).toString();
然后当我尝试用 phpseclib 解码它时
$key = 'A5178B6A965AACF3CD60B07A15061719';
$data = /*text encrypted by JS*/;
$cipher = new AES();
$cipher->setKeyLength(256);
$cipher->setKey($key);
$res = $cipher->decrypt($data);
然后$res变成空串
我做错了什么?
如果您将字符串作为密钥传递给 CryptoJS.<cipher>.encrypt
,CryptoJS 会将其视为密码,并将使用带有随机盐的 OpenSSL EVP_BytesToKey
和一次迭代从中派生出实际密钥MD5。
phpseclib 没有它的实现,所以你可以传入实际的密钥:
var key256Bits = CryptoJS.enc.Utf8.parse('A5178B6A965AACF3CD60B07A15061719');
由于这个密钥只有32个hexits长,它只有128位的熵,但仍然使用AES-256。您需要 64 个十六进制,您可以在使用前对其进行解码以获得 32 个字节的安全密钥大小。
此外,phpseclib 实现了 PKCS#7 填充,因此您需要使用
padding: CryptoJS.pad.Pkcs7
在 CryptoJS 中。
示例 JavaScript 代码:
var iv = CryptoJS.enc.Hex.parse('00000000000000000000000000000000'); //it's for tests, later it will be dynamically generated
var key256Bits = CryptoJS.enc.Utf8.parse('A5178B6A965AACF3CD60B07A15061719');
var cipher = CryptoJS.AES.encrypt(
'Some text',
key256Bits,
{
iv: iv,
padding: CryptoJS.pad.Pkcs7
}
).toString();
console.log(cipher)
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/aes.js"></script>
在PHP中,使用前需要确保解密密文:
$data = base64_decode("IWkBG3A46rNrxwWN2JD7xQ==");
$key = 'A5178B6A965AACF3CD60B07A15061719';
$cipher = new AES();
$cipher->setKeyLength(256);
$cipher->setKey($key);
$res = $cipher->decrypt($data);
var_dump($res);
安全考虑:
如果您只使用对称加密,您需要在服务器和客户端使用完全相同的密钥。如果您将加密密钥从服务器发送到客户端或以其他方式发送,您需要加密您的对称加密密钥。最简单的方法是使用 TLS。如果您使用 TLS,那么数据和密钥都会被加密,因此您不需要自己加密。这不提供任何安全性,只是有点混淆。你应该阅读:https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/