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

前端 未结 1 549
南方客
南方客 2021-01-14 01:55

At first, Node.js crypto.

// Both of key and IV are hex-string, but I hide them in Stackoverflow.

var secretKey  = new Buffer(\'aaaaaaaaaaaaaaaaaaaaaaaaaa         


        
相关标签:
1条回答
  • 2021-01-14 02:14

    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");
    }
    
    0 讨论(0)
提交回复
热议问题