Node.js aes128encryption/解密端口到PHP

所以在node.js我有一个encryptionscheme使用aes128而不通过IV。 一个例子如下

var cipher = require('crypto').createCipher('aes128','password'); cipher.update('test','utf8','base64')+cipher.final('base64'); 

输出CjZ3R/tW8jiyLvg+/TE6bA== 。 问题是,我不能在PHP中重现这一点,即使我已经尝试了一堆实现和变化。

当我然后尝试通过openssl运行这个,我运行以下:

  echo "test" | openssl enc -e -aes128 -a -k password 

输出U2FsdGVkX19Ccfv3SWvuzuZWeov9GDuwx1RMK2HWa / s =也不匹配。 我也尝试使用-md和所有可能的选项,并且两者都不匹配(它们甚至不是相同的块大小)。 在PHP中运行时,我尝试过使用填充(padding)对填充字符进行散列操作(填充字符是所需填充字符的数目)(在网上看到这是nodejs使用的内容)。 我已经尝试将IV设置为密码,也尝试将空字节,但我仍然无法获得匹配。

任何build议/想法?

编辑:

所以我刚刚在php中发现了函数openssl_encrypt,并尝试了相同的testing,并再次得到了一个完全不同的输出(现在这个输出与node.js完全相同,据说它们都使用openssl):

  openssl_encrypt ( "test" , 'aes128' , "password") 

哪些输出(已经在base64中) JleA91MvYHdEdnj3KYHmog==这是至less现在在块计数匹配,但仍然不是相同的密文。

我还应该提到的是,将IV传递给nodejs是一种select,可以解决这个差异,但是这个phpscheme将取代已经存在的nodejs中的旧scheme,所以它必须能够解密已经创build的密文

所以我想出了解决scheme。 在查看node.js的c ++源代码之后,我发现使用openssl函数EVP_BytesToKey生成密钥和iv。 在search这个函数的实现后,我发现这个堆栈溢出后在Cocoa中encryption数据,在PHP中解码(反之亦然) ,其中包含该函数的一个版本。 修改并添加openssl版本填充数据的事实与ascii字符等于填充所需的字节数我想出了以下函数完全匹配nodejsencryptionscheme:

 function aes128Encrypt($key, $data) { $padding = 16 - (strlen($data) % 16); $data .= str_repeat(chr($padding), $padding); $keySize = 16; $ivSize = 16; $rawKey = $key; $genKeyData = ''; do { $genKeyData = $genKeyData.md5( $genKeyData.$rawKey, true ); } while( strlen( $genKeyData ) < ($keySize + $ivSize) ); $generatedKey = substr( $genKeyData, 0, $keySize ); $generatedIV = substr( $genKeyData, $keySize, $ivSize ); print($generatedIV); print($generatedKey); return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $generatedKey, $data, MCRYPT_MODE_CBC, $generatedIV); } 

与node.js函数完全匹配:

  function aes128Encrypt(key,data) { var cipher = require('crypto').createCipher('aes128',key); return cipher.update(data,'utf8','binary')+cipher.final('binary'); }