Node.js`crypto.final`使得encryption的结果不同于PHP`mcrypt_encrypt`
起初,Node.jsencryption。
// Both of key and IV are hex-string, but I hide them in Stackoverflow. var secretKey = new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), // 48 chars iv = new Buffer('bbbbbbbbbbbbbbbb', 'hex'); // 16 chars var str = 'This string will be encrypted.'; var cipher = crypto.createCipheriv('des-ede3-cbc', secretKey, iv), cryptedStr = cipher.update(str, 'utf8', 'base64') + cipher.final('base64');
然后,PHP mcrypt。
$key = pack('H*', "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); $iv = pack('H*', "bbbbbbbbbbbbbbbb"); $string = 'This string will be encrypted.'; $text = mcrypt_encrypt(MCRYPT_3DES, $key, $string, MCRYPT_MODE_CBC, $iv); $text_base64 = base64_encode($text);
问题。
在相同的string中,相同的algorithm和相同的编码。
仍然有一点不匹配,那就是cipher.final()
。
以下是真实的样本输出。
// Node.js output. UKBI17EIHKNM2EU48ygsjil5r58Eo1csByAIFp9GhUw= ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Same part // PHP output. UKBI17EIHKNM2EU48ygsjil5r58Eo1csAY4C0JZoyco= ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Same part
为什么cipher.final()
使结果不同?
在不修改PHP代码的情况下,如何在Node.js中做出相同的结果。
由于您无法更改您的PHP代码,因此您需要修改node.js代码。
问题是node.js的encryption模块只使用PKCS#7填充,而PHP只使用零填充。 但是,您可以禁用node.js中的填充( setAutoPadding(false)
)来实现您自己的零填充:
function zeroPad(buf, blocksize){ if (typeof buf === "string") { buf = new Buffer(buf, "utf8"); } var pad = new Buffer((blocksize - (buf.length % blocksize)) % blocksize); pad.fill(0); return Buffer.concat([buf, pad]); }
像这样使用它:
var secretKey = new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), // 48 chars iv = new Buffer('bbbbbbbbbbbbbbbb', 'hex'); // 16 chars var str = 'This string will be encrypted.'; var cipher = crypto.createCipheriv('des-ede3-cbc', secretKey, iv); cipher.setAutoPadding(false); var cryptedStr = cipher.update(zeroPad(str, 8), 'utf8', 'base64') + cipher.final('base64'); console.log(cryptedStr);
输出:
UKBI17EIHKNM2EU48ygsjil5r58Eo1csAY4C0JZoyco=
下面是一个匹配的unpad函数的实现:
function zeroUnpad(buf, blocksize){ var lastIndex = buf.length; while(lastIndex >= 0 && lastIndex > buf.length - blocksize - 1) { lastIndex--; if (buf[lastIndex] != 0) { break; } } return buf.slice(0, lastIndex + 1).toString("utf8"); }
- AES256encryption在node.js和objective-c之间得到不同的结果
- 解密来自PHP RIJNDAEL_128 CBC的node.js中的string
- NodeJS aes解密不起作用
- 检查zip或gzip是否是密码encryption的(Node.JS)
- 使用Amazon KMSencryption值,使用带有Lambda的DynamoDB存储/检索(NodeJS)
- 为什么Node.js的符号和CryptographicEngine符号结果有区别?
- 为BaseJS编码PGPencryption的二进制文件在base64中
- 节点中的椭圆曲线门限密码体制
- 什么是bcrypt与节点一起使用的替代scheme?