6-4
Wednesday
标签
梦涛笔记

由ECIES加密算法引发编写了RSAIES加密方法

PHP 发布时间:2025-05-28 20:54:36

ECDSA (Elliptic Curve Digital Signature Algorithm,椭圆曲线数字签名算法)

相比RSA算法密钥更短安全性更高,验签速度也更快,使用场景也得到广泛应用。

因为ECDSA算法只能做签名,不能做加解密,所以产生了ECIES(Elliptic Curve Integrated Encryption Scheme,椭圆曲线集成加密方案)。

ECIES 其中用到的 ECDH算法生成共享密钥,因平台兼容问题一些旧系统还无法支持。

所以依照ECIES的加密思路设计了自己的RSAIES加密方法:

RSAIES 加密方式详解
  • 生成随机AES密钥,使用 RSA 加密方法对其加密
  • 生成随机AES密钥iv值
  • 用随机AES密钥对数据进行AES-128-CFB加密,参数 OPENSSL_RAW_DATA
  • 密文和iv值进行base64处理(支持HEX)
  • 使用SHA256计算哈希值(mac),用于接收者验证数据完整性
  • 把 加密的随机AES密钥 cipher 向量 iv 编码方式 code 密文哈希值 mac 加密类型 RSAIES 放入 encryption 字段
RSAIES 解密方式详解
  • 把接收到的密文使用SHA256计算哈希值,验证mac值是否相同,判定数据是否完整
  • 把接收到的 加密的随机AES密钥 cipher 编码还原 base64_decode 后,使用 RSA 解密方法对其解密得到AES密钥原文
  • 用得到的随机AES密钥和收到的向量 iv 采用 aes-128-cfb 进行解密, 参数 OPENSSL_RAW_DATA
  • 得到原文


示例代码: https://github.com/unntech/encrypt/blob/main/src/RSA.php
    /**
     * RASIES加密
     * 生成随机AES密钥,使用 RSA 加密方法对其加密
     * 使用AES-128-CFB加密文本,参数选 OPENSSL_RAW_DATA
     * @param string $plaintext 明文数据
     * @param string $code 密文编码支持 base64 | hex | bin
     * @return false | array 
     *     [ 'cipher' => '加密的AES密钥', 
     *       'iv'     => 'iv',  
     *       'code'   => 'base64', 
     *       'ciphertext' => '密文', 
     *       'mac'    => '密文SHA256哈希' 
     *     ]
     * 
     */
    public function encrypt_ies(string $plaintext, string $code = 'base64', int $padding = OPENSSL_PKCS1_PADDING )
    {
        $publicKey = $this->third_public_key;
        // 生成随机对称密钥
        $cipher_method = 'aes-128-cfb';
        $symmetricKey = openssl_random_pseudo_bytes(16); // 使用 AES-128 密钥长度
        $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher_method));
        // 使用公钥加密对称密钥(使用 RASIES 过程)
        openssl_public_encrypt( $symmetricKey, $encryptedKey, $publicKey, $padding );
        // 使用对称密钥加密消息(AES-128-CFB)
        $encryptedMessage = openssl_encrypt($plaintext, $cipher_method, $symmetricKey, OPENSSL_RAW_DATA, $iv);
        $ciphertext = Encode::encode($encryptedMessage, $code );
        //使用SHA256计算密文哈希值
        $mac = strtoupper(hash("sha256", $ciphertext));

        // AES密钥cipher、向量iv、密文及哈希值
        return [
            'cipher_method' => $cipher_method,
            'cipher'        => Encode::encode($encryptedKey, $code),
            'iv'            => Encode::encode($iv, $code),
            'code'          => $code,
            'ciphertext'    => $ciphertext,
            'mac'           => $mac,
        ];
    }

    /**
     * RASIES 解密
     * 使用RSA解密方法对 $cipher 解密,得到AES密钥
     * 使用AES-128-CFB解密密文,参数选 OPENSSL_RAW_DATA,得到明文
     * @param string $ciphertext 密文
     * @param string $cipher 加密的AES密钥
     * @param string $iv AES加密向量
     * @param string|null $mac 密文哈希值
     * @param string $code 编码
     * @param int $padding 填充方式(OPENSSL_PKCS1_PADDING / OPENSSL_NO_PADDING)
     * @return string|null
     */
    public function decrypt_ies(string $ciphertext, string $cipher = '', string $iv = '', ?string $mac = null, string $code = 'base64', int $padding = OPENSSL_PKCS1_PADDING): ?string
    {
        // 解密对称密钥
        openssl_private_decrypt(Encode::decode($cipher, $code), $symmetricKey, $this->private_key, $padding);
        if(empty($symmetricKey)){
            return null;
        }
        // 2. 验证 MAC
        if(!is_null($mac)){
            $_mac = strtoupper(hash("sha256", $ciphertext));
            if($mac != $_mac){
                return null;
            }
        }
        // 3. 解密密文
        $plaintext = openssl_decrypt(Encode::decode($ciphertext, $code), 'aes-128-cfb', $symmetricKey, OPENSSL_RAW_DATA, Encode::decode($iv, $code));

        return $plaintext;
    }


RSAIES Integrated Encryption Scheme)RSA集成加密方案,采取了RSA使用广泛及跨平台兼容性高的优点,方案中只用RSA加解密随机AES密钥。

然后用AES进行对称加密数据,相比RSA加密快,又不用处理长文本RSA加密复杂的缺点。


评论: