我正在尝试从CryptoJS加密一些文本并用Phalcon解密它。
我加密如下,
CryptoJS.AES.encrypt("MyText", 'key123');
现在比较我用Phalcon加密相同的值,
$this->crypt = new Crypt();
$this->crypt->encrypt("MyText", 'key123');
现在我从JS和PHP获得的值是不同的。
Phalcon默认加密是AES,CryptoJS也是如此。
请帮我解决这个问题。我希望双方都有相同的价值。
答案 0 :(得分:3)
Phalcon中的默认密码是Rijndael-256,CryptoJS不支持。有必要将其更改为Rijndael-128(AES)。在Phalcon中使用某种填充模式也是必要的,以便能够加密任意二进制数据。
$keyHex = "0102030405060708090a0b0c0d0e0f";
$this->crypt = new Crypt();
$this->crypt->setPadding($this->crypt->PADDING_PKCS7);
$this->crypt->setCipher("rijndael-128");
// encryption
$ct = base64_encode($this->crypt->encrypt("MyText", hex2bin($keyHex)));
// decryption
var_dump($this->crypt->decrypt(base64_decode($ct), hex2bin($keyHex)));
128位初始化向量以密文为前缀,因此必须在CryptoJS中以相同的方式完成。
var key = CryptoJS.enc.Hex.parse("0102030405060708090a0b0c0d0e0f");
var iv = CryptoJS.lib.WordArray.random(128/8);
var ct = CryptoJS.AES.encrypt("MyText", key, {
iv: iv
}).ciphertext;
return iv.concat(ct).toString(CryptoJS.enc.Base64);
注意事项:
密钥必须随机生成。这是一个示例16字节密钥(32个十六进制),它必须具有特定长度。 AES支持16,24和32字节(32,48,64十六进制)的密钥大小。
每次加密都会随机生成IV,因此无法使用CryptoJS和Phalcon中的相同密钥加密相同的文本以检查兼容性。有必要在一个加密,在另一个解密。
没有身份验证的对称加密可能非常危险。在你的情况下可能会安装padding-oracle攻击。添加身份验证的常用方法是使用单独的密钥在IV +密文上运行消息身份验证代码。在这方面,采用encrypt-then-MAC方案的HMAC-SHA256是一个很好的选择。
如果“key”作为字符串传递给CryptoJS.AES.encrypt
,则它会调用OpenSSL兼容的密钥派生函数(EVP_BytesToKey
)。假定给定的“密钥”是密码,因此它生成一个随机盐,并从这两个中导出实际密钥和IV。
Phalcon使用的是mcrypt,它是放弃软件并且有很多错误。