crypto-js 与 php-mcrypt AES 加密/解密

Posted

技术标签:

【中文标题】crypto-js 与 php-mcrypt AES 加密/解密【英文标题】:crypto-js versus php-mcrypt AES crypt/decrypt 【发布时间】:2014-09-12 05:21:52 【问题描述】:

我正在尝试编写一个跨语言加密/解密工具(javascriptphp/mcryp),但我有点卡住了。

你可以在这里找到我的js代码http://jsbin.com/siyesaqa/31/edit,而我的php代码是这样的:

class Manager


    /**
     * @param string $content
     * @param string $passphrase
     * @return string
     */
    public static function encrypt($plain, $passphrase = null) 
        $salt = mcrypt_create_iv(
            128 / 8,
            MCRYPT_DEV_URANDOM
        );
        $cipher = hash_pbkdf2(
            "sha256",
            $passphrase ? $passphrase : $_ENV['SECURITY_KEY'],
            $salt,
            100,
            128 / 8
        );
        $iv = mcrypt_create_iv(
            mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC),
            MCRYPT_RAND
        );
        $encrypted = mcrypt_encrypt(
            MCRYPT_RIJNDAEL_128,
            $cipher,
            $plain,
            MCRYPT_MODE_CBC,
            $iv
        );
        return base64_encode($salt) . base64_encode($iv) . base64_encode($encrypted);
    

    /**
     * @param string $encContent
     * @param string $passphrase
     * @return string
     */
    public static function decrypt($encrypted, $passphrase = null) 
        $encrypted = base64_decode($passphrase ? $passphrase : $_ENV['SECURITY_KEY']);
        $salt = substr($encrypted, 0, 128 / 8);
        $cipher = hash_pbkdf2("sha256", $passphrase, $salt, 1000, 128 / 8);
        $iv = substr($encrypted, 128 / 8, 128 / 8);
        return trim(mcrypt_decrypt(
            MCRYPT_RIJNDAEL_128,
            $cipher,
            substr($encrypted, 128 / 8 * 2),
            MCRYPT_MODE_CBC,
            $iv
        ), "\0\t");
    

如您所见,我在为 salt 和 cipher 变量返回相同值时遇到了一些麻烦。

哪位对这两个库有更多经验的人可以给我一个提示吗?

非常感谢您。

【问题讨论】:

【参考方案1】:

您的 JavaScript 加密函数对 salt 和 IV 进行十六进制编码,而 PHP 函数 Base64 对它们进行编码。不过,这两个函数都使用 Base64 对密文进行编码。

此外,您的 PHP 解密函数似乎使用了 1000 轮 PBKDF2,而所有其他函数使用了 100 轮。

【讨论】:

我已经想通了……我想:jsbin.com/siyesaqa/36/edit。我认为,我现在唯一的问题是,虽然 php PBKDF2 返回我一个 16 字符的字符串,但 CryptoJS 返回我一个 32 字符的字符串。我只在谈论 php 加密 - CryptoJs 解密。一旦我弄清楚了这些,我确定我可以得到 js 加密 - php 解密。 @DragosCirjan 当您在 CryptoJS Cipher 对象上调用 toString() 时,它会将密文十六进制编码为字符串。相反,您没有在 PHP 中对密文进行编码。这很令人困惑,因为在 PHP 中,字符串和字节数组是一回事。 对不起。我的笔记本电脑在我更新 php 加密功能之前就死了(所以我不得不等待再次接通电源)。正如我所说...我的最后一个问题(关注)是 PBKDF2 字符串,我仍然不知道如何使其等效于(从 js 到 php 或 php 到 js)。 在***.com/questions/24884661/… 中回答了自己。放弃这个想法。

以上是关于crypto-js 与 php-mcrypt AES 加密/解密的主要内容,如果未能解决你的问题,请参考以下文章

在 CentOS 6 上安装 php-mcrypt

我在哪里可以获得 PHP 7 的 php-mcrypt?

在 CentOS 上安装时的 php-mcrypt 依赖问题(最新服务器版本)

Laravel https 和 Auth 需要 php-mcrypt 吗?

微信小程序crypto-js AES 加解密数据

uniapp 与C# 加解密