兼容性AES-256-CBC节点/ Laravel

时间:2016-09-26 09:58:21

标签: php node.js laravel ssl encryption

我正在尝试创建一个与Laravel的加密模块兼容的哈希。 以下是Laravel的参考源代码:https://github.com/illuminate/encryption/blob/master/Encrypter.php#L101-163

以下是我的经历:

const encrypt = function (payload) {
    const iv = crypto.randomBytes(16);
    const key = new Buffer(config.stuff.key, 'base64');

    const cipher  = crypto.createCipheriv('aes-256-cbc', key, iv);
    cipher.setAutoPadding(false); // With or without this /!\
    let value = cipher.update(serialize(JSON.stringify(payload)), 'utf8', 'base64');

    value + cipher.final('base64');

    const mac = crypto.createHmac('sha256', new Buffer(config.stuff.key, 'base64')).update(iv.toString('base64') + value).digest('hex');

    const json = JSON.stringify({ iv: iv.toString('base64'), value, mac });

    return base64_encode(json);
};

不幸的是,当我尝试时,我有一个BAD_DECRYPT。这似乎来自OpenSSL的填充。有没有人有想法?

1 个答案:

答案 0 :(得分:1)

这应该有效:

const encrypt = function (payload) {
    const iv = crypto.randomBytes(16);
    const key = new Buffer(config.stuff.key, 'base64');

    const cipher  = crypto.createCipheriv('aes-256-cbc', key, iv);
    let value = cipher.update(serialize(payload), 'utf8');

    value = Buffer.concat([value, cipher.final()]).toString('base64');

    const mac = crypto.createHmac('sha256', key)
            .update(iv.toString('base64') + value)
            .digest('hex');

    const json = JSON.stringify({ 
        iv: iv.toString('base64'), 
        value: value, 
        mac: mac 
    });

    return base64_encode(json);
};

问题:

  • openssl_encrypt自动使用PKCS#7填充,node.js也自动使用。
  • 连接多个Base64字符串以形成单个Base64编码的字符串并不总是有效,因为两个字符串中的第一个可能包含填充字符(=),这意味着前一个字符的所有位都不属于到密文。其中一些只是虚拟位。这就是Base64的工作原理。

PHP的serizalize可以移植到JavaScript,如here所示。