将 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=
我目前正在对 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=