Node.js `crypto.final` make the encrypted result is different to PHP `mcrypt_encrypt`

六眼飞鱼酱① 提交于 2019-12-01 07:33:33

Since you can't change your PHP code, you will need to modify the node.js code.

The problem is that node.js' crypto module uses only PKCS#7 padding, whereas PHP uses only zero padding. You can however disable padding in node.js (setAutoPadding(false)) to implement your own zero padding:

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]);
}

And use it like this:

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);

Output:

UKBI17EIHKNM2EU48ygsjil5r58Eo1csAY4C0JZoyco=

Here is an implementation of a matching unpad function:

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");
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!