加密基础回顾:对称与非对称加密

说实话,每次带新人做安全项目时,我总要先问一个问题:你清楚对称加密和非对称加密到底差在哪吗? 很多人能背出定义,但一到选算法、设计密钥分发方案时就懵了。这一节我们就来扎实地过一遍,我会把我这些年踩过的坑一并抖出来。

对称加密:一把钥匙开一把锁

对称加密的原理特别直观:加密和解密用的是同一把密钥。就像你家防盗门,一把钥匙既能锁门也能开门。发送方和接收方手里得有完全一样的密钥副本。

举个常见的例子:你给同事发一个加密的ZIP包,告诉他密码是「MyP@ss2025」。他输入这个密码解压,这个过程就是对称加密。我在早期做数据流加密时,经常用AES-256-GCM来保护公网管道里的报文——速度快,硬件指令集也支持。

典型算法:AES

AES(Advanced Encryption Standard)是目前最主流的对称算法。它有三个变种:AES-128、AES-192、AES-256,密钥长度越长就越难破解。你想想,128位密钥就有3.4×10³⁸种组合,暴力破解基本不现实。

我建议在项目里至少用AES-256-GCM(Galois/Counter Mode),因为GCM模式自带认证标签,能防篡改。曾经我在一个IoT项目里图省事只用了ECB模式,结果密文出现明显的模式重复——嗯,这种低级错误后来再也没犯过。

对称加密的本质优势: 速度快,适合大量数据;短板:密钥分发难,通信双方必须在安全通道上先交换密钥。

非对称加密:两把钥匙,公钥加密私钥解密

非对称加密彻底解决了密钥分发问题:每个人生成一对密钥——公钥公开,私钥自己藏好。别人用你的公钥加密消息,只有你用私钥才能解开。反过来,你用私钥签名,别人用公钥验证签名,这就是数字签名的雏形。

老实说,我第一次接触RSA时觉得“公钥能随意公开”特别反直觉。直到有一次做邮件加密,我把公司所有人的公钥放在一个共享文件夹里——真的可以,因为公钥不需要保密。但要保护好私钥,否则什么都白搭。

典型算法:RSA

RSA是目前最经典的非对称算法,基于大整数分解的数学难题。它的密钥长度至少2048位(我绝不推荐1024位,已经被攻破了)。RSA加密会消耗较多CPU资源,所以实际中很少用它加密大批量数据,而是用来交换对称密钥——这叫“混合加密”。

维度AES(对称)RSA(非对称)
密钥数量1个共享密钥公钥+私钥 一对
速度极快(硬件加速可达GB/s)慢(通常<1 MB/s)
安全性基础密钥随机性大整数分解难题
典型应用文件加密、VPN、数据库字段证书、密钥交换、数字签名

为什么需要混合加密?

你想想,如果全用RSA加密一个1GB的视频,光加密就要跑好几分钟,CPU还滚烫。反之,如果只靠AES加密,密钥怎么安全地传给对方?

所以实际项目中几乎都是“混合”着来的:先用RSA加密一个随机生成的AES密钥,再用这个AES密钥加密真正的数据。我做过的一个支付网关,就是TLS握手时用RSA(或ECDHE)协商临时密钥,后续传输全走AES-GCM。

避坑指南: 我曾经在混合加密中直接用RSA加密大数据,结果性能测试直接打脸。记住:RSA只能加密比密钥短的数据,AES才是主力干活的那个。

对称 vs 非对称:一张图看懂

对称加密 vs 非对称加密原理对比 对称加密 (AES) 加密与解密使用同一把密钥 速度极快,适合大数据量 密钥必须通过安全通道分发 非对称加密 (RSA) 公钥加密,私钥解密 速度慢,适合少量数据 公钥公开,私钥保密 密钥 需加密传输 典型流程:使用AES加密数据 双方预先持有相同密钥 典型流程:使用RSA加密密钥 接收方分发公钥,发送方加密临时密钥 实际方案:混合加密 RSA加密AES密钥 → AES加密大块数据

代码速览:AES-256-GCM 与 RSA-OAEP

我不打算贴冗长的工程代码,但给你一个能跑的最小示例,方便理解两者如何配合使用。

AES 对称加密(Python + cryptography 库)

from cryptography.hazmat.primitives.ciphers.aead import AESGCM

key = AESGCM.generate_key(bit_length=256)
aesgcm = AESGCM(key)
nonce = b'\x00' * 12  # 实际要用随机 nonce
ciphertext = aesgcm.encrypt(nonce, b"这是机密数据", aad=None)
# 解密:plaintext = aesgcm.decrypt(nonce, ciphertext, aad=None)

RSA 非对称加密(Python + cryptography 库)

from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization

private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()
ciphertext = public_key.encrypt(
    b"短内容或密钥",
    padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),
                  algorithm=hashes.SHA256(), label=None))
# 解密:plaintext = private_key.decrypt(ciphertext, ...)
注意: RSA 直接加密数据长度受限——2048位密钥最多只能加密256字节(实际能加密245字节左右,因为OAEP填充要占一些空间)。千万别用RSA去加密大文件,否则运行时直接崩给你看。我当年就是这样被运维同事追着骂了半小时……

如何根据内容选择加密策略?

这一章只是基础回顾,但我已经忍不住想预告(好吧,不说预告)——后续我们会深入讨论:什么时候只用对称加密、什么时候非对称必不可少、以及如何根据内容类型(小字段、大文件、流媒体)做决策。

但此刻,你只要掌握这个核心结论:拿到一个加密需求,优先问自己——密钥怎么安全分发? 如果已经有安全通道,对称加密又快又省心;如果需要在不安全信道上交换密钥,那就用非对称加密保护这个瓶颈。

个人习惯: 我会把对称加密当作主力加密引擎,非对称加密当作密钥分发管道。两者的结合——混合加密——才是现代密码工程的常态。