将 PHP 加密转换为 NodeJS

Converting PHP encryption to NodeJS

我目前正在对 API 实施加密。我必须按照在 PHP.

中编写的特定脚本中加密和解密的相同方式来实现它

当我以 base64 格式输出结果时,一切正常。 PHP decrypt 方法针对它运行并且工作正常。问题是由于某些要求,我需要输出的不是 base64,而是二进制,但是当我从 Nodejs 端加密为二进制时,结果与我在 PHP 中加密为二进制时应该是不同的一样。

PHP 加密:

function vd_encrypt($plaintext, $password) {
$method = "AES-256-CBC";
$key = hash('sha256', $password, true);
$iv = openssl_random_pseudo_bytes(16);

$ciphertext = openssl_encrypt($plaintext, $method, $key, OPENSSL_RAW_DATA, $iv);
$hash = hash_hmac('sha256', $ciphertext, $key, true);

return $iv . $hash . $ciphertext;

}

Javascript 加密:

import crypto from 'crypto';

export function encrypt (plain_text: string): string {
    const encryptionMethod = 'AES-256-CBC';
    const iv = crypto.randomBytes(IV_LENGTH);
    const key = crypto.createHash("sha256").update(secret).digest();

    var encryptor = crypto.createCipheriv(encryptionMethod, key, iv);

    const result = iv + encryptor.update(plain_text, 'utf8', 'binary') + encryptor.final('binary');

    return result;
}

我稍微更新了您的代码以接受 iv 参数。您可以按照与以前相同的方式生成它(例如 openssl_random_pseudo_bytes)。

出于演示目的,我将使用固定 IV,以便我们可以显示相同的结果。

PHP

function vd_encrypt($plaintext, $password, $iv) {
    $method = "AES-256-CBC";
    $key = hash('sha256', $password, true);
    $ciphertext = openssl_encrypt($plaintext, $method, $key, OPENSSL_RAW_DATA, $iv);
    $hash = hash_hmac('sha256', $ciphertext, $key, true);
    return $iv . $hash . $ciphertext;
}

// Replace with below code in production
// $iv = openssl_random_pseudo_bytes(16);
$iv = base64_decode("eQMrc61Gt8qRejRjhJOkVw==");
$result = vd_encrypt("He was a man take him for all in all, I shall not look upon his like again", "password", $iv);

echo "Result (base64): " . base64_encode($result) . "\n";

Node.js

import crypto from 'crypto';

export function encrypt (plaintext: string, password: string, iv: string): string {
    const encryptionMethod = 'AES-256-CBC';
    const key = crypto.createHash("sha256").update(password).digest();
    const encryptor = crypto.createCipheriv(encryptionMethod, key, iv);

    const encryptedData = Buffer.concat([encryptor.update(plaintext, 'utf8'), encryptor.final()]);
    const hash = crypto.createHmac("sha256", key).update(encryptedData).digest();

    return Buffer.concat([iv, hash, encryptedData]);
}

// Replace with below code in production 
//const iv = crypto.randomBytes(16);
const iv = Buffer.from("eQMrc61Gt8qRejRjhJOkVw==", "base64");
const result = encrypt("He was a man take him for all in all, I shall not look upon his like again", "password", iv);
console.log("Result (base64):", result.toString("base64"));

在这种情况下,结果将如下所示:

PHP:

Result (base64): eQMrc61Gt8qRejRjhJOkVxsqZTqUjSUnaL46yZDLGGK5+o7WKLyIiG4UKj0ST93Wi7UlaAyTFIjpIs0C893SFsnHeuVshG+6EJF99GrLSUCMFJG3J1pJnmxF4Pu8ZCbN7Ounp0BjhJKIpu9yQn6uEYylJLXWpzNw+aCwsnIV1h0=

Node.js:

Result (base64): eQMrc61Gt8qRejRjhJOkVxsqZTqUjSUnaL46yZDLGGK5+o7WKLyIiG4UKj0ST93Wi7UlaAyTFIjpIs0C893SFsnHeuVshG+6EJF99GrLSUCMFJG3J1pJnmxF4Pu8ZCbN7Ounp0BjhJKIpu9yQn6uEYylJLXWpzNw+aCwsnIV1h0=