在php中RSA加密解密,密钥长度和填充方式两种参数,它们直接影响加密的安全性和兼容性,甚至影响加密解密成功与否
密钥长度:
- RSA 常用的密钥长度有 1024、2048、3072 和 4096 位。
- 密钥长度越长,加密强度越高,因为要分解
- 密钥长度越长,加密和解密所需的计算资源越多。长密钥加密解密速度较慢,占用更多的处理时间和存储空间。
- 推荐 通常 2048 位 RSA 密钥在大多数情况下足够安全,4096 位更为安全但速度会更慢。具体选择需要在安全性和性能之间权衡
填充方式:
RSA 使用填充方式来确保加密的安全性。填充方式决定了在加密前如何处理明文,防止一些潜在的攻击
- RSA_PKCS1_PADDING 方式
PKCS#1 v1.5 标准中的填充方式,必须比 RSA 钥模长短至少11个字节, 也就是 RSA_size(rsa) – 11,
比如 2048 位密钥可以加密的数据最大为 245 字节 - RSA_PKCS1_OAEP_PADDING 方式
PKCS#1 v2.0 中引入的填充方式,与 PKCS#1 v1.5 相比安全性有很大提升.
它占用了更多空间(一般为 41字节),也就是 RSA_size(rsa) – 41
例如,2048 位密钥可以加密的明文最大为 214 字节 - RSA_NO_PADDING 方式
不填充,可以和RSA钥模长一样长
RSA加密具有确定性,给定的明文和密钥,每次加密的输出密文都将是相同的,这种确定性容易带来安全风险,大量密文统计分析下,容易被推断其中一些敏感明文内容。
同样RSA具有延展性,在不解密密文的情况下,攻击者可以对密文进行特定的数学操作,使明文发生可预测的变化,容易被篡改。
推荐使用 RSA_PKCS1_OAEP_PADDING,避免使用 RSA_PKCS1_PADDING 和 RSA_NO_PADDING 一个过期一个不安全。
注意:密钥长度和填充方式相互影响,相同长度的密钥不同填充方式,可以加密的数据长度不相同。
rsa 例子
<?php
class RSAEncryption {
private $privateKey;
private $publicKey;
public function __construct($keyLength = 2048) {
$this->generateKeys($keyLength);
}
// 生成密钥对
private function generateKeys($keyLength) {
$config = [
"private_key_bits" => $keyLength,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
];
// 生成私钥资源
$res = openssl_pkey_new($config);
openssl_pkey_export($res, $this->privateKey); // 导出私钥
$publicKeyDetails = openssl_pkey_get_details($res);
$this->publicKey = $publicKeyDetails["key"]; // 获取公钥
}
// 获取公钥
public function getPublicKey() {
return $this->publicKey;
}
// 获取私钥
public function getPrivateKey() {
return $this->privateKey;
}
// 使用公钥加密
public function encryptWithPublicKey($data, $padding = OPENSSL_PKCS1_PADDING) {
if (!openssl_public_encrypt($data, $encryptedData, $this->publicKey, $padding)) {
throw new Exception("公钥加密失败:" . openssl_error_string());
}
return base64_encode($encryptedData); // 返回加密后的base64编码
}
// 使用私钥解密
public function decryptWithPrivateKey($encryptedData, $padding = OPENSSL_PKCS1_PADDING) {
if (!openssl_private_decrypt(base64_decode($encryptedData), $decryptedData, $this->privateKey, $padding)) {
throw new Exception("私钥解密失败:" . openssl_error_string());
}
return $decryptedData; // 返回解密后的明文
}
// 使用私钥加密
public function encryptWithPrivateKey($data, $padding = OPENSSL_PKCS1_PADDING) {
if (!openssl_private_encrypt($data, $encryptedData, $this->privateKey, $padding)) {
throw new Exception("私钥加密失败:" . openssl_error_string());
}
return base64_encode($encryptedData); // 返回加密后的base64编码
}
// 使用公钥解密
public function decryptWithPublicKey($encryptedData, $padding = OPENSSL_PKCS1_PADDING) {
if (!openssl_public_decrypt(base64_decode($encryptedData), $decryptedData, $this->publicKey, $padding)) {
throw new Exception("公钥解密失败:" . openssl_error_string());
}
return $decryptedData; // 返回解密后的明文
}
}