由ECIES加密算法引发编写了RSAIES加密方法
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加密复杂的缺点。