木子屋 Dnawo's BLOG

对称加密 (AES) 与非对称加密 (RSA) 完整示例

👤 dnawo 📅 2026-10-13 👁 24 👍 1 💬 0 🔄 本站原创 📂 Web编程
对称加密像一把钥匙开一把锁,加密和解密都用同一把密钥,这样操作很高效,但只适合少数互信方之间共享密钥的场景,一旦要在多人、开放环境中通信,就必须先把这把密钥安全地交给对方,密钥分发和保管就成了最大难题。非对称加密则用一对密钥:公钥和私钥。公钥公开,私钥自留,公钥加密,私钥解密,公钥加密后只有私钥能解,因此不需要提前安全传递密钥,适合群体间通信、开放网络和互不信任的环境,正好解决了对称加密的密钥传输问题。不过非对称加密速度慢,通常只用来协商或传递临时对称密钥,真正的大数据仍用对称加密。

1、对称加密:AES-256-GCM

对称加密时,加密和解密用同一把密钥,速度快,适合加密大量数据。

<?php
// 对称加密:AES-256-GCM
$plaintext = "对称加密 - MZWU.COM";
$cipher = "aes-256-gcm";

// 256 位密钥,实际中要安全保存
$key = random_bytes(32);

// 初始化向量,类似随机盐,每次随机生成,GCM 推荐 12 字节 IV
$iv = random_bytes(12);
// 认证标签,验证密文有没有被篡改
$tag = '';

// 加密
$ciphertext = openssl_encrypt(
    $plaintext,
    $cipher,
    $key,
    OPENSSL_RAW_DATA,
    $iv,
    $tag
);

if ($ciphertext === false) {
    exit("加密失败: " . openssl_error_string() . PHP_EOL);
}

// 实际传输/存储时:iv + tag + 密文 一起保存
$payload = base64_encode($iv . $tag . $ciphertext);
echo "加密后: {$payload}\n";

// 解密
$raw = base64_decode($payload, true);
$iv2 = substr($raw, 0, 12);       // IV 12 字节
$tag2 = substr($raw, 12, 16);     // GCM tag 默认 16 字节
$ciphertext2 = substr($raw, 28);  // 剩下的密文

$decrypted = openssl_decrypt(
    $ciphertext2,
    $cipher,
    $key,
    OPENSSL_RAW_DATA,
    $iv2,
    $tag2
);

if ($decrypted === false) {
    exit("解密失败: " . openssl_error_string() . PHP_EOL);
}

echo "解密后: {$decrypted}\n";

2、非对称加密:RSA-OAEP

非对称加密时,加密和解密用一对密钥:公钥和私钥。公钥公开,私钥自留,公钥加密,私钥解密。非对称加密速度慢,只能加密短数据。

先生成一对 RSA 密钥:

openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in private.pem -out public.pem

非对称加密例子:

<?php
// 非对称加密:RSA-OAEP
$plaintext = "非对称加密 - MZWU.COM";

$privateKey = openssl_pkey_get_private(file_get_contents('private.pem'));
$publicKey  = openssl_pkey_get_public(file_get_contents('public.pem'));

if ($privateKey === false || $publicKey === false) {
    exit("密钥加载失败: " . openssl_error_string() . PHP_EOL);
}

// 公钥加密
if (!openssl_public_encrypt(
    $plaintext,
    $encrypted,
    $publicKey,
    OPENSSL_PKCS1_OAEP_PADDING
)) {
    exit("加密失败: " . openssl_error_string() . PHP_EOL);
}

$encryptedBase64 = base64_encode($encrypted);
echo "加密后: {$encryptedBase64}\n";

// 私钥解密
if (!openssl_private_decrypt(
    base64_decode($encryptedBase64, true),
    $decrypted,
    $privateKey,
    OPENSSL_PKCS1_OAEP_PADDING
)) {
    exit("解密失败: " . openssl_error_string() . PHP_EOL);
}

echo "解密后: {$decrypted}\n";

因为速度慢,只能加密短数据,所以实际系统里通常用 RSA 加密一个临时的 AES 密钥,再用 AES 加密真正的大数据。此外,非对称加密除了用于加密外,还经常用于数字签名,私钥签名,公钥验签。

评论(0)

暂无评论。

计算题
评论需审核通过后显示
← 上一篇 Windows 10文件夹删除所有已继承的权限无法打开解决方法