JavaScript 和 PHP 中不同的 AES 加密

Posted

技术标签:

【中文标题】JavaScript 和 PHP 中不同的 AES 加密【英文标题】:Different AES Encrypt in JavaScript and PHP 【发布时间】:2022-01-18 06:53:00 【问题描述】:

我想用 php 加密数据。 我之前用过一个javascript代码来加密。

JavaScript 代码:

const SHARED_KEY="XXelkee4v3WjMP81fvjgpNRs2u2cwJ7n3lnJzPt8iVY=";

const ZERO_IV=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];

let data="6104337983063890";

aesEncrypt = async (data) => 
        try
            let key =  new Uint8Array(this.base64ToArray(SHARED_KEY));
            let aes = new aesJs.ModeOfOperation.cbc(key, ZERO_IV)
            let bData = aesJs.utils.utf8.toBytes(data);
            let encBytes = aes.encrypt(aesJs.padding.pkcs7.pad(bData))
            return this.arrayToHex(encBytes)
        catch(err) 
            console.error(err)
            return null
        
     

PHP 代码:

$sharedSecret=base64_decode('XXelkee4v3WjMP81fvjgpNRs2u2cwJ7n3lnJzPt8iVY=');

$iv = '0000000000000000';

$data="6104337983063890";
            
$output = openssl_encrypt(
    $data,
    'AES-128-CBC',
    $sharedSecret,
    OPENSSL_RAW_DATA,
    $iv
);

$output=bin2hex($output);

两种语言的输出是:

JavaScript: 4b685c988d9e166efd0bc5830e926ae0d60111d9dd73d7b4f3c547282994546f (正确)

PHP: 091da5cf4ffd853e58f5b4f0a07902219ce7ac9647801af5b3e8f755d63b71b4

我需要使用 PHP 进行加密,这与 JavaScript 相同。

【问题讨论】:

我是基于this answer 的created/modifed my gist on GitHub。我希望它对你有用。 提醒一下,即使你在JS中加密数据,代码仍然会显示秘密等,这可能是未来的安全风险。 【参考方案1】:

您必须在 PHP 代码中使用aes-256-cbc 作为算法,因为密钥是 32 字节大。

您还必须在 PHP 代码中应用一个零向量作为 IV,您可以使用以下方法创建:

$iv = hex2bin('00000000000000000000000000000000');

这样,PHP 代码提供与 JavaScript 代码相同的密文。


请注意,静态 IV 是不安全的。正确的方法是为每次加密生成一个随机(非秘密)IV,并将该 IV 与密文一起传递给解密方(通常是串联的)。

【讨论】:

以上是关于JavaScript 和 PHP 中不同的 AES 加密的主要内容,如果未能解决你的问题,请参考以下文章

AES 的 Javascript 实现与 PHP 的 mcrypt 兼容

AES加密使用Php,javascript,反之亦然

使用 PHP mcrypt 加密后使用 Javascript CryptoJS 解密 AES

如何使用Javascript中的AES CBC零填充进行加密并使用Java进行解密

javascript与php使用aes进行加密/解密

使用 mcrypt 在 php 和 c 中进行 AES 加密