分类
碎碎念

PHP 加解密 CryptoJS 默认 AES 加解密

CryptoJS 提供了非常方便的加密接口 CryptoJS.AES.encrypt 和解密接口 CryptoJS.AES.decrypt,但是这两个接口对于其他语言来说就非常不友好。比如 PHP 就不能直接使用 openssl 的组件来加解密,好在 PHP 已有人给出解决办法。

Node.js 要使用也比较简单,直接引入 CryptoJS 就可以开始使用,其他语言也应该有人提供了解决办法。

class CryptoJS
{
    static public function aesEncrypt($data, $key)
    {
        $salted = 'Salted__';
        $salt = openssl_random_pseudo_bytes(8);

        $config = self::generateKey($key, $salt);
        $encrypt = openssl_encrypt(
            $data,
            'AES-256-CBC',
            $config['key'],
            OPENSSL_RAW_DATA, // base64 was already decoded
            $config['iv']
        );

        return base64_encode($salted . $salt . $encrypt);
    }

    static public function aesDecrypt($data, $key)
    {
        $data = base64_decode($data);
        if (substr($data, 0, 8) != 'Salted__') {
            return false;
        }
        $salt = substr($data, 8, 8);
        $config = self::generateKey($key, $salt);

        return openssl_decrypt(
            substr($data, 16),
            'AES-256-CBC',
            $config['key'],
            OPENSSL_RAW_DATA, // base64 was already decoded
            $config['iv']
        );
    }

    static protected function generateKey(
        $password,
        $salt,
        $keySize = 8,
        $ivSize = 4,
        $iterations = 1,
        $hashAlgorithm = 'md5'
    )
    {
        $targetKeySize = $keySize + $ivSize;
        $derivedBytes = '';
        $numberOfDerivedWords = 0;
        $block = null;
        $hasher = hash_init($hashAlgorithm);
        while ($numberOfDerivedWords < $targetKeySize) {
            if ($block != null) {
                hash_update($hasher, $block);
            }
            hash_update($hasher, $password);
            hash_update($hasher, $salt);
            $block = hash_final($hasher, true);
            $hasher = hash_init($hashAlgorithm);

            // Iterations
            for ($i = 1; $i < $iterations; $i++) {
                hash_update($hasher, $block);
                $block = hash_final($hasher, true);
                $hasher = hash_init($hashAlgorithm);
            }
    
            $derivedBytes .= substr(
                $block,
                0,
                min(strlen($block), ($targetKeySize - $numberOfDerivedWords) * 4)
            );
            $numberOfDerivedWords += strlen($block) / 4;
        }

        return [
            'key' => substr($derivedBytes, 0, $keySize * 4),
            'iv' => substr($derivedBytes, $keySize * 4, $ivSize * 4),
        ];
    }
}

来源:Encrypt with PHP, Decrypt with Javascript (cryptojs) - Stack Overflow

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据