Aji*_*ith 4 php encryption openssl node.js node-crypto
我有一个在 php 上运行的应用程序,其中使用下面的代码使用 openssl encrption 加密了一些值
<?php
define('OSSLENCKEY','14E2E2D1582A36172AE401CB826003C1');
define('OSSLIVKEY', '747E314D23DBC624E971EE59A0BA6D28');
function encryptString($data) {
$encrypt_method = "AES-256-CBC";
$key = hash('sha256', OSSLENCKEY);
$iv = substr(hash('sha256', OSSLIVKEY), 0, 16);
$output = openssl_encrypt($data, $encrypt_method, $key, 0, $iv);
$output = base64_encode($output);
return $output;
}
function decryptString($data){
$encrypt_method = "AES-256-CBC";
$key = hash('sha256', OSSLENCKEY);
$iv = substr(hash('sha256', OSSLIVKEY), 0, 16);
$output = openssl_decrypt(base64_decode($data), $encrypt_method, $key, 0, $iv);
return $output;
}
echo encryptString("Hello World");
echo "<br>";
echo decryptString("MTZHaEoxb0JYV0dzNnptbEI2UXlPUT09");
?>
Run Code Online (Sandbox Code Playgroud)
我有另一个在 nodejs 上运行的端点,我需要根据上面的 php 加密/解密规则来解密和加密值。我已经搜索过但找不到解决方案。
我尝试使用该库crypto但最终出现错误参考
我尝试过的nodejs代码如下
message = 'MTZHaEoxb0JYV0dzNnptbEI2UXlPUT09';
const cypher = Buffer.from(message, "base64");
const key = crypto.createHash('sha256').update('14E2E2D1582A36172AE401CB826003C1');//.digest('hex');
// $iv = substr(hash('sha256', '747E314D23DBC624E971EE59A0BA6D28'), 0, 16); from php returns '0ed9c2aa27a31693' need nodejs equivalent
const iv = '0ed9c2aa27a31693';
const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
console.log( decipher.update(contents) + decipher.final());
Run Code Online (Sandbox Code Playgroud)
有人请帮我找到一个用于openssl加密和解密的nodejs代码
提前致谢
代码中存在以下问题:
另请注意,使用静态 IV 是不安全的(但您可能只是出于测试目的才这样做)。
以下 NodeJS 代码生成与 PHP 代码相同的密文:
const crypto = require('crypto');
const plain = 'Hello World';
const hashKey = crypto.createHash('sha256');
hashKey.update('14E2E2D1582A36172AE401CB826003C1');
const key = hashKey.digest('hex').substring(0, 32);
const hashIv = crypto.createHash('sha256');
hashIv.update('747E314D23DBC624E971EE59A0BA6D28');
const iv = hashIv.digest('hex').substring(0, 16);
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
var encrypted = cipher.update(plain, 'utf-8', 'base64');
encrypted += cipher.final('base64');
encrypted = Buffer.from(encrypted, 'utf-8').toString('base64');
console.log(encrypted); // MTZHaEoxb0JYV0dzNnptbEI2UXlPUT09
encrypted = Buffer.from(encrypted, 'base64').toString('utf-8');
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
var decrypted = decipher.update(encrypted, 'base64', 'utf-8');
decrypted += decipher.final('utf-8');
console.log(decrypted); // Hello World
Run Code Online (Sandbox Code Playgroud)
编辑:
正如注释中提到的,PHP 的hash()方法默认将哈希值作为十六进制字符串返回(除非第三个参数显式设置为true,但参考代码中并非如此)。这使得长度加倍,因为在这种编码中,散列的每个字节都由两个十六进制数字(hexits)表示,即 2 个字节。
因此有必要缩短 NodeJS 代码中的密钥(参见我原来答案的第一点)。这种缩短在 PHP 代码中是不必要的,因为 PHP隐式地执行了此操作(这实际上是一个设计缺陷,因为这样用户就不会注意到密钥可能存在问题)。
使用十六进制字符串有两个缺点:
由于这些原因,使用哈希的原始二进制数据而不是十六进制编码的字符串更加安全和稳健。如果您想这样做,则需要进行以下更改。
在 PHP 代码中:
$key = hash('sha256', OSSLENCKEY, true);
$iv = substr(hash('sha256', OSSLIVKEY, true), 0, 16);
Run Code Online (Sandbox Code Playgroud)
在 NodeJS 代码中:
const key = hashKey.digest();
const iv = hashIv.digest().slice(0, 16)
Run Code Online (Sandbox Code Playgroud)
但请注意,此版本与旧版本不兼容,即更改前的加密在更改后无法解密。因此,旧数据必须迁移。
| 归档时间: |
|
| 查看次数: |
4501 次 |
| 最近记录: |