RSA 加密解密是一种非对称加密算法,在数据安全中应用广泛。RSA 使用两个密钥进行加密解密:公钥(public key)和 私钥(private key)。其中,公钥用于加密数据,私钥用于解密数据。

在 PHP 中,可以使用内置的 openssl 扩展来实现 RSA 加密和解密。

1. 安装 OpenSSL 扩展

首先,确保 PHP 已经启用了 openssl 扩展。你可以通过以下命令检查:

php -m | grep openssl

如果未启用,可以在 php.ini 中取消注释以下行:

extension=openssl

然后重启 Web 服务器或 PHP-FPM。

2. RSA 加密解密的基本流程

2.1 生成公钥和私钥

在使用 RSA 加密解密前,你需要生成一对公钥和私钥。通常,你可以使用 OpenSSL 命令行工具生成密钥对,或者在 PHP 中直接生成。

2.1.1 使用 OpenSSL 命令行生成密钥对
openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in private.pem -out public.pem
  • private.pem:存储私钥。
  • public.pem:存储公钥。

你可以通过上述命令生成 2048 位的 RSA 密钥对。

2.1.2 在 PHP 中生成密钥对
<?php
// 生成 RSA 密钥对
$private_key_resource = openssl_pkey_new([
    "private_key_bits" => 2048,
    "private_key_type" => OPENSSL_KEYTYPE_RSA,
]);

// 导出私钥
openssl_pkey_export($private_key_resource, $private_key);

// 获取公钥
$public_key_resource = openssl_pkey_get_details($private_key_resource);
$public_key = $public_key_resource['key'];

echo "Private Key: \n$private_key\n";
echo "Public Key: \n$public_key\n";
?>

3. RSA 加密和解密

3.1 加密过程

RSA 加密通常使用公钥进行。使用 openssl_public_encrypt 函数将数据加密。

3.1.1 使用公钥进行加密
<?php
// 公钥
$public_key = "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7B5bdW9DtOUJ8lF0M5v2Aq
...
-----END PUBLIC KEY-----";

// 待加密数据
$data = "Hello, this is a secret message.";

// 使用公钥加密
openssl_public_encrypt($data, $encrypted, $public_key);

echo "Encrypted data: " . base64_encode($encrypted) . "\n";
?>
  • openssl_public_encrypt($data, $encrypted, $public_key):此函数将 $data 使用公钥加密,结果存储在 $encrypted 变量中。

加密后的数据通常会进行 Base64 编码,方便传输和存储。

3.2 解密过程

RSA 解密使用私钥进行。使用 openssl_private_decrypt 函数来解密数据。

3.2.1 使用私钥解密
<?php
// 私钥
$private_key = "-----BEGIN PRIVATE KEY-----
MIIEowIBAAKCAQEA7B5bdW9DtOUJ8lF0M5v2AqT1LsOdZbgx9nvYge0wPo5Z5dcv
...
-----END PRIVATE KEY-----";

// 加密数据
$encrypted_data = base64_decode("gFz+zE2NzfrZVOTjhkF...");  // 这是通过公钥加密的密文

// 使用私钥解密
openssl_private_decrypt($encrypted_data, $decrypted, $private_key);

echo "Decrypted data: " . $decrypted . "\n";
?>
  • openssl_private_decrypt($encrypted_data, $decrypted, $private_key):此函数将加密数据 $encrypted_data 使用私钥解密,结果存储在 $decrypted 变量中。

4. 完整的示例代码

结合上面的代码,下面是一个完整的 RSA 加密解密示例:

<?php
// 生成 RSA 密钥对
$private_key_resource = openssl_pkey_new([
    "private_key_bits" => 2048,
    "private_key_type" => OPENSSL_KEYTYPE_RSA,
]);

// 导出私钥
openssl_pkey_export($private_key_resource, $private_key);

// 获取公钥
$public_key_resource = openssl_pkey_get_details($private_key_resource);
$public_key = $public_key_resource['key'];

echo "Private Key: \n$private_key\n";
echo "Public Key: \n$public_key\n";

// 待加密数据
$data = "Hello, this is a secret message.";

// 使用公钥加密
openssl_public_encrypt($data, $encrypted, $public_key);
$encrypted_data = base64_encode($encrypted);
echo "Encrypted data: " . $encrypted_data . "\n";

// 使用私钥解密
openssl_private_decrypt(base64_decode($encrypted_data), $decrypted, $private_key);
echo "Decrypted data: " . $decrypted . "\n";
?>

5. 注意事项

  • 密钥的长度:RSA 加密的安全性与密钥的长度密切相关,推荐使用 2048 位或更高的密钥长度来保证安全性。
  • 加密块大小限制:RSA 的加密和解密有块大小限制。每个加密操作的最大数据大小受密钥长度限制。对于 2048 位的密钥,单次加密的数据最大为 245 字节。因此,如果需要加密较大的数据,可以使用对称加密(如 AES)先加密数据,再使用 RSA 加密对称密钥。
  • 私钥保密性:私钥必须严格保密,一旦泄露,RSA 加密的安全性就失效。

6. 优化与扩展

  • 使用对称加密:如上所述,RSA 加密适合加密小数据量,对于大数据量的加密,推荐使用对称加密(如 AES)。可以使用 RSA 加密一个对称密钥,然后用该对称密钥加密大数据。
  • 数据签名与验证:RSA 也常用于数字签名和验证。在数据加密外,还可以使用私钥对数据进行签名,公钥进行验证。
// 签名
openssl_sign($data, $signature, $private_key, OPENSSL_ALGO_SHA256);

// 验证签名
$is_verified = openssl_verify($data, $signature, $public_key, OPENSSL_ALGO_SHA256);

总结

通过 PHP 的 openssl 扩展,RSA 加密解密可以非常容易地实现。你可以使用公钥进行加密,使用私钥进行解密,同时也可以进行签名和验证。通过合理的密钥管理和加密策略,你可以有效地保证数据的安全性。