[英]encryption result differs in PHP and Node.js
我使用带有空白iv和密钥(16 0)的AES 128 CBC加密字符串“ aaaaaaaaaaaaaaaaaa”(16字节UTF8字符串),并获得不同的结果
在PHP中:
echo base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128,pack("H*", "00000000000000000000000000000000"),"aaaaaaaaaaaaaaaa",MCRYPT_MODE_CBC,pack("H*", "00000000000000000000000000000000")))
返回“ kmwP6gWv1l9ZMdKanGs / nA ==”
在Node.js中:
let cipher = require('crypto').createCipheriv('aes-128-cbc',Buffer.alloc(16),Buffer.alloc(16))
console.log(cipher.update('aaaaaaaaaaaaaaaa','utf8','base64') + cipher.final('base64'))
返回“ kmwP6gWv1l9ZMdKanGs / n HeUidae8Z4dK0HU7p2z + 1c =”
第一位(固定)与PHP相同,但是PHP值具有一个额外的“ A =”,然后Node值具有一个完整的额外“ HeUidae8Z4dK0HU7p2z + 1c”
我承认我对这里发生的事情非常不满意-我在这里想念什么?
编辑 ...但不是那么摇晃,以至于我不明白我在这里所做的并不是特别安全。 不必担心这是否是进行加密的“正确”方法-请关注结果应该对齐的事实。
edit2-但是,我可以使用十六进制而不是base64进行封闭-
PHP:926c0fea05afd65f5931d29a9c6b3f9c
节点: 926c0fea05afd65f5931d29a9c6b3f9c 779489d69ef19e1d2b41d4ee9db3fb57
Node十六进制的第二个块是由.final方法返回的,我不明白它的用途。
AES的块大小为16个字节。 您正在加密字符串“ hello world”,该字符串在UTF8中长11个字节。 因此,使用填充将字符串的长度增加到16个字节。
节点以及它应该使用的PKCS5填充将您的纯文本填充到16个字节,然后对其进行加密。
mcrypt 不应使用零字节来填充纯文本,这是不应该的 。 mcrypt已被弃用 ,并且已经废弃了十年。
因为您的两种填充方案不同,所以纯文本实际上甚至在我们应用AES之前就已经不同。
我的建议:在PHP中使用openssl_*
函数。 并且不要使用静态IV。 使用静态IV会使您的程序容易遭受与ECB模式相同的某些漏洞,这不好!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.