需要帮助以使用加密将Encryption Blowfish php转换为Nodejs

问题描述 投票:1回答:1

您好,我需要使用加密模块将我的PHP加密函数转换为Nodejs的帮助:

此代码已经有效

// Constructor params
$this->algorithm = "blowfish";
$this->token = "3SzzaErRzj0#RuGr@JTkh[MO0AMIW*d!Sul/CEL!*rPnq$oOEgYaH}fNw{jw1b/DyLUdL])+JOMES@Z7MIRI>(p*nY{yl%h]4ylx";

    public function decrypt($string)
    {

        $key = hash('sha256', $this->token);
        list($encrypted_data, $iv) = explode('::', base64_decode($string), 2);
        return openssl_decrypt($encrypted_data, $this->algorithm, $key, 0, $iv);
    }

    public function encrypt($string)
    {

        $output = false;
        $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($this->algorithm));
        // hash
        $key = hash('sha256', $this->token);
        $output = openssl_encrypt($string, $this->algorithm, $key, 0, $iv);
        return base64_encode($output . '::' . $iv);
    }

和nodejs中的代码,我使解密工作正常,但是密码不工作

    const crypto = require('crypto');

    const decipher = async (alg, key, value) => {
            const hash = crypto.createHash('sha256');
            hash.update(key);
            let token = hash.digest('hex');

            let buff = new Buffer.from(value, 'base64');
            let [encrypted, iv] = buff.toString('ascii').split('::', 2);
            iv = new Buffer.from(iv);

            const decipher = crypto.createDecipheriv(alg, token, iv);
            let decrypted = await decipher.update(encrypted, 'base64', 'ascii');
            decrypted += decipher.final('ascii');
            return decrypted;
    }

   /* this one is not working */
   const cipher = async (alg, key, value) => {


        let iv = crypto.randomBytes(8);

        var sha256 = crypto.createHash('sha256');
        sha256.update(key);
        var newkey = sha256.digest('base64');

        var encryptor = await crypto.createCipheriv(alg, newkey, iv);

        encrypted = encryptor.update(value, 'utf8', 'base64') + encryptor.final('base64');

        var final = encrypted + "::" +iv;

        let buf = Buffer.from(final);
        let encodedData = buf.toString('base64');

        return encodedData;

}

感谢任何帮助我完成工作的帮助

php node.js encryption cryptojs
1个回答
1
投票

必须在NodeJS代码的cipher方法中进行以下更改:

  • 密钥必须以十六进制编码:

    var newkey = sha256.digest('hex'); 
    
  • IV必须附加为二进制字符串:

    var final = encrypted + "::" + iv.toString('binary');
    
  • 并且必须将数据解析为二进制字符串:

    let buf = Buffer.from(final, 'binary');
    

通过这些更改,NodeJS代码中的cipher方法与PHP代码中的encrypt方法兼容。

cipher方法使用UTF8编码,decipher方法使用ASCII编码,因此只有ASCII编码文本可以正确解密。要消除对ASCII编码的限制,在decipher方法中需要进行以下更改:

  • 编码为二进制字符串必须使用binary而不是ascii

    let [encrypted, iv] = buff.toString('binary').split('::', 2);
    iv = new Buffer.from(iv, 'binary');
    
  • 并且输出编码必须为utf8而不是ascii

    let decrypted =  decipher.update(encrypted, 'base64', 'utf8');
    decrypted += decipher.final('utf8');
    

通过这些更改,NodeJS和PHP代码是兼容的。另请注意:

  • 实际上,没有一个NodeJS函数是异步的,因此实际上不需要使用async / await
  • new之前的Buffer.from可以省略。
  • [blowfish指定了算法,它对应于bf-cbc,表示CBC模式下的河豚。
  • 32字节密钥是使用SHA256生成的,并以十六进制字符串(具有64字节/字符)的形式返回,因此使用了64字节密钥。对于河豚,定义的最大密钥长度为56个字节,here
  • SHA256用作密钥派生功能,例如, PBKDF2(至少对于弱密码而言),here
  • 用定界符分隔的IV附加到Base64编码的密文中,并且对所得数据进行Base64编码(即,因此密文对Base64进行了两次编码)。通常,IV和密文(按此顺序)在二进制级别上连接在一起,并且结果数据是Base64编码的。分隔符不是必需的,因为IV的长度对应于块大小,因此是已知的。
© www.soinside.com 2019 - 2024. All rights reserved.