gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 02:55:04 24 4
gpt4 key购买 nike

您好,我需要帮助使用加密模块将我的 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中的代码,我使decipher工作正常,但cipher不工作

    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;

}

任何帮助我完成工作的帮助我都很感激

最佳答案

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

  • key 必须采用十六进制编码:

    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 并不是真正必要的。
  • Buffer.from之前的new可以省略。
  • 算法由blowfish指定,对应于bf-cbc,表示CBC模式下的Blowfish。
  • 使用 SHA256 生成 32 字节 key 并以十六进制字符串(64 字节/字符)形式返回,因此使用 64 字节 key 。对于 Blowfish,定义了 56 个字节的最大 key 长度,here .
  • SHA256用作 key 导出函数,更安全,例如PBKDF2(至少对于弱密码),here .
  • 由分隔符分隔的 IV 附加到 Base64 编码的密文中,并且生成的数据经过 Base64 编码(即密文因此经过 Base64 编码两次)。通常,IV 和密文(按此顺序)在二进制级别上连接,所得数据采用 Base64 编码。分隔符不是必需的,因为 IV 的长度对应于 block 大小,因此是已知的。

关于php - 需要帮助使用加密将 Encryption Blowfish php 转换为 Nodejs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61280983/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com