gpt4 book ai didi

javascript - 使用 CryptoJS (JAVASCRIPT) 和 OpenSSL (PHP) 实现相同的加密

转载 作者:行者123 更新时间:2023-12-05 03:48:26 24 4
gpt4 key购买 nike

我想在 ReactJS 应用程序中实现 PhP 加密功能。我需要以使用 OpenSSL 库函数 (openssl_encrypt) 创建的特定格式发送 token 。

与 JAVASCRIPT 函数相比,PHP 函数生成的字符串短了几个字符。当然,两者都具有相同的属性。

PHP:

protected static function encrypt($stringData) {
$encrypted = false;
$encrypt_method = 'AES-256-CBC';
$iv = substr(hash('sha256', static::$ivMessage), 0, 16);
$encrypted= openssl_encrypt($stringData, $encrypt_method, static::$apiSecret, 0, $iv);

return $encrypted;
}

JavaScript:

export const encrypt = (stringData) => {
const iv = CryptoJS.SHA256(IV_MESSAGE).toString(CryptoJS.enc.Hex).substring(0, 16);
const encrypted = CryptoJS.AES.encrypt(stringData, API_SECRET, {
iv,
mode: CryptoJS.mode.CBC,
pad: CryptoJS.pad.ZeroPadding,
});

return encrypted;
};

示例常量:

const stringData = "{"uid":19,"price":10000000,"duration":240,"credit_purpose":5,"new_tab":false,"cssFile":"kalkulatorok","css":[],"supported":false,"email":"test@test.hu","productType":"home_loan","method":"calculator","calculatorType":"calculator","unique":true}";
const IV_MESSAGE = "a";
const API_SECRET = "secret_key";

(PHP 函数相同 --> $stringData, $ivMessage; $apiSecret)

如何实现在JAVASCRIPT 中“复制”PHP 函数?到目前为止我错过了什么?

最佳答案

CryptoJS 代码中的以下更改对于生成 PHP 代码的密文是必要的:

  • key 必须作为 WordArray 传递。如果它作为字符串传递,它被解释为 passphrase从中派生出一个 32 字节的 key 。
  • PHP 使用 0x00 值填充太短的键,直到达到指定长度。 CryptoJS 不会这样做,并且(由于 bug )通常在无效 key 的情况下为 AES 使用未定义的整数,因此预计不会有匹配的密文。
  • PHP 代码中使用了 PKCS7 填充(见评论)。这也必须应用于 CryptoJS 代码,但是它是 default (以及 CBC 模式)。

以下 PHP 代码:

function encrypt($stringData) {

$ivMessage = "a";
$apiSecret = "secret_key";

$encrypted = false;
$encrypt_method = 'AES-256-CBC';
$iv = substr(hash('sha256', $ivMessage), 0, 16);
$encrypted= openssl_encrypt($stringData, $encrypt_method, $apiSecret, 0, $iv);

return $encrypted;
}

$stringData = '{"uid":19,"price":10000000,"duration":240,"credit_purpose":5,"new_tab":false,"cssFile":"kalkulatorok","css":[],"supported":false,"email":"test@test.hu","productType":"home_loan","method":"calculator","calculatorType":"calculator","unique":true}';
print(encrypt($stringData) . "\n");

返回结果:

d/H+FfTaT/3tIkaXtIix937p6Df/vlnxagNJGJ7ljj48phT7oA7QssTatL3WNZY0Igt0r5ObGyCt0AR0IccVTFVZdR+nzNe+RmKQEoD4dj0mRkZ7qi/y3bAICRpFkP3Nz42fuILKApRtmZqGLTNO6dwlCbUVvjg59fgh0wCzy15g51G6CYLsEHa89Dt193g4qcXRWFgI9gyY1Gq7FX0G6Ers0fySQjjNcfDJg0Hj5aSxbPU6EPn14eaWqkliNYSMqzKhe0Ev7Y54x2YlUCNQeLZhwWRM2W0N+jGU7W+P/bCtF4Udwv4cweUESXkHLGtlQ0K6O5etVJDtb7ZtdEI/sA==

下面的 CryptoJS 代码生成相同密文:

const IV_MESSAGE = "a";
const API_SECRET = "secret_key\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";

function encrypt(stringData){
const iv = CryptoJS.SHA256(IV_MESSAGE).toString(CryptoJS.enc.Hex).substring(0, 16);
const encrypted = CryptoJS.AES.encrypt(
stringData,
CryptoJS.enc.Utf8.parse(API_SECRET),
{
iv: CryptoJS.enc.Utf8.parse(iv)
});

return encrypted;
};

const stringData = {"uid":19,"price":10000000,"duration":240,"credit_purpose":5,"new_tab":false,"cssFile":"kalkulatorok","css":[],"supported":false,"email":"test@test.hu","productType":"home_loan","method":"calculator","calculatorType":"calculator","unique":true};
const ciphertextB64 = encrypt(JSON.stringify(stringData)).toString();

console.log(ciphertextB64.replace(/(.{64})/g,'$1\n'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

还应考虑以下因素:

  • 生成IV时避免将IV编码为十六进制字符串,直接使用二进制数据更可靠。否则,您还必须记住,根据平台的不同,通常可以应用不同大小写的十六进制数字。这在这里并不重要,因为在这两种情况下都使用小写。
  • 如果您真的应该应用像 secret_key 这样的密码短语作为 key ,您还应该使用合理的 key 派生函数(例如 PBKDF2 结合随机生成的盐),因为熵较低。 CryptoJS 中使用的默认 KDF,专有的 OpenSSL 函数 EVP_BytesToKey , 不应被应用,因为它不是标准并且也被认为是相对不安全的。
  • 出于安全原因,不得使用静态 IV。相反,应为每次加密应用随机生成的 IV。 IV 不是 secret 的,通常按照 IV 的顺序与密文连接,密文(见评论)。

关于javascript - 使用 CryptoJS (JAVASCRIPT) 和 OpenSSL (PHP) 实现相同的加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64379332/

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