加密基础回顾:对称与非对称加密
说实话,每次带新人做安全项目时,我总要先问一个问题:你清楚对称加密和非对称加密到底差在哪吗? 很多人能背出定义,但一到选算法、设计密钥分发方案时就懵了。这一节我们就来扎实地过一遍,我会把我这些年踩过的坑一并抖出来。
对称加密:一把钥匙开一把锁
对称加密的原理特别直观:加密和解密用的是同一把密钥。就像你家防盗门,一把钥匙既能锁门也能开门。发送方和接收方手里得有完全一样的密钥副本。
举个常见的例子:你给同事发一个加密的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。
对称 vs 非对称:一张图看懂
代码速览: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, ...)
如何根据内容选择加密策略?
这一章只是基础回顾,但我已经忍不住想预告(好吧,不说预告)——后续我们会深入讨论:什么时候只用对称加密、什么时候非对称必不可少、以及如何根据内容类型(小字段、大文件、流媒体)做决策。
但此刻,你只要掌握这个核心结论:拿到一个加密需求,优先问自己——密钥怎么安全分发? 如果已经有安全通道,对称加密又快又省心;如果需要在不安全信道上交换密钥,那就用非对称加密保护这个瓶颈。