PHP RSA 非对称加密解密完整实现

星野
星野
发布时间:2026-10-13 | 2人浏览过
原创

在使用 PHP 构建开放 API 或进行服务端与客户端交互时,RSA 非对称加密是保护敏感数据传输的关键手段。本文将详细说明如何利用 OpenSSL 库生成公私钥对,并通过 PHP 代码实现完整的加密与解密操作,确保数据在不安全信道中的安全性。

结果与目标

通过本教程,你将掌握在非对称加密场景下,利用 OpenSSL 扩展在 PHP 中生成密钥、加载密钥资源,并使用私钥加密/公钥解密(或反之)的方法。核心目标是生成一对可互通的密钥,并在代码中验证其加解密功能。

准备条件

确保你的服务器环境已安装并启用了 PHP 的 OpenSSL 扩展,这是处理 RSA 算法的基础。同时,你需要一个能够执行命令行指令的环境(如 Linux、macOS 或 Windows 下的 CMD/PowerShell),用于生成初始密钥文件。

第1步:使用 OpenSSL 命令行生成密钥对

目的:获取可用于 RSA 加解密的原始私钥文件和标准化的公钥文件。

入口:系统终端或命令行界面。

动作:进入你喜欢的独立文件夹,依次执行以下三条命令:

  1. 生成 1024 位(建议生产环境至少 2048 位)的原始 RSA 私钥文件:
    openssl genrsa -out rsa_private_key.pem 1024

  2. 将原始私钥转换为 PKCS#8 格式,便于程序读取:
    openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem

  3. 基于原始私钥派生出对应的公钥文件:
    openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

参数说明:生成的 private_key.pem 应严格保密,仅由服务器端持有;rsa_public_key.pem 则分发给 Android、iOS 等客户端用于发送加密数据。

第2步:在 PHP 代码中加载密钥

目的:将 PEM 格式的密钥字符串解析为 OpenSSL 可用的资源标识符。

入口:PHP 脚本文件(如 index.php)。

动作:直接使用单引号定义包含头尾标记的密钥字符串,然后调用 openssl_pkey_get_private() 和 openssl_pkey_get_public() 函数获取资源 ID。这一步可用于验证密钥格式是否正确,若返回 false 则表示密钥无效。

<?php
// 此处省略具体的密钥内容字符串,实际使用时请替换为第1步生成的真实内容
$private_key = '-----BEGIN PRIVATE KEY-----
...(此处需填入 private_key.pem 的内容)...
-----END PRIVATE KEY-----';

$public_key = '-----BEGIN PUBLIC KEY-----
...(此处需填入 rsa_public_key.pem 的内容)...
-----END PUBLIC KEY-----';

// 验证并获取密钥资源
$pi_key = openssl_pkey_get_private($private_key);
$pu_key = openssl_pkey_get_public($public_key);

if (!$pi_key || !$pu_key) {
    die('密钥加载失败,请检查密钥格式');
}
?>

第3步:执行加解密操作

目的:演示两种最常见的非对称加密组合:私钥签名/公钥验签(通常配合摘要,此处仅演示基础加密),以及公钥加密/私钥解密(常用于数据传输)。

入口:PHP 脚本逻辑部分。

动作:使用 openssl_private_encrypt 和 openssl_public_decrypt 模拟私钥加密、公钥解密流程。由于加密后的二进制数据可能包含特殊字符,必须使用 base64_encode 进行编码以便于存储或通过网络 URL 传输。

<?php
$data = "aassssasssddd";// 原始明文数据
$encrypted = ""; 
$decrypted = ""; 

echo "源数据:", $data, "\n";

// 1. 私钥加密
openssl_private_encrypt($data, $encrypted, $pi_key);
$encrypted_b64 = base64_encode($encrypted);
echo "私钥加密后(Base64):", $encrypted_b64, "\n";

// 2. 公钥解密
openssl_public_decrypt(base64_decode($encrypted_b64), $decrypted, $pu_key);
echo "公钥解密后:", $decrypted, "\n";

echo "---------------------------------------\n"

// 3. 公钥加密(适用于客户端发数据给服务端)
openssl_public_encrypt($data, $encrypted, $pu_key);
$encrypted_b64 = base64_encode($encrypted);
echo "公钥加密后(Base64):", $encrypted_b64, "\n";

// 4. 私钥解密
openssl_private_decrypt(base64_decode($encrypted_b64), $decrypted, $pi_key);
echo "私钥解密后:", $decrypted, "\n";
?>

完成判断与排错

完成状态:上述代码正常输出“源数据”与“解密后”的数据完全一致,即表示加解密链路打通。

常见排错:

  • 乱码或解密失败:检查是否在解密前使用了正确的 base64_decode。如果直接对未解码的二进制数据进行解密,将导致不可预测的结果。
  • 密钥不匹配:确保 $pi_key 和 $pu_key 来源于同一对生成的密钥,且 PKCS#8 转换过程未出错。
  • 长度限制:RSA 加密有最大明文长度限制(对于 1024 位密钥约为 86-117 字节,取决于填充模式)。大文本应采用混合加密模式(如 RSA 加密 AES 密钥,再用 AES 加密数据)。

简要总结

RSA 非对称加密能有效解决 API 交互中的身份认证与数据安全传输问题。关键在于正确生成 PKCS#8 格式的私钥,以及在代码中规范地处理 Base64 编解码。以上就是 PHP RSA 非对称加密解密方法的详细内容,更多关于 PHP 安全编程的资料请关注本站其它相关文章!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表