第二讲 密码学基础回顾:对称加密,非对称加密,哈希函数
密码学听起来离我们很远,但核心就那么几块。说白了,密钥边界设计就是研究“钥匙该放哪、怎么用、谁来管”,绕不开这些老伙计。
我这些年做密钥管理,踩过最大的坑就是:把密码学工具当成黑盒,读完文档就往上堆。结果呢?线上爆过内存泄露,也出过密钥混淆。嗯,今天咱们先打好底。
2.1 对称加密:一把钥匙开一把锁
对称加密,加解密用的是同一把密钥。就好比你用同一把钥匙锁门和开门。速度极快,适合加密大量数据。
核心特征: 加密=解密密钥相同。安全性完全依赖密钥的保密性。
常见的对称算法大致分两类:
- 分组密码:AES、SM4、DES。把明文切成固定大小的块,一块一块加密。AES 的密钥长度可选 128/192/256,现在行业最低标准是 AES-128。
- 流密码:ChaCha20、RC4。逐字节或逐位加密,适合数据流场景。我曾在物联网项目中用过 ChaCha20,资源消耗比 AES 小很多。
用 Python 写个 AES-CBC 的例子,感受一下:
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import os
key = os.urandom(32) # 256 位密钥
iv = os.urandom(16) # 初始向量
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = b"密钥边界设计实战"
ciphertext = cipher.encrypt(pad(plaintext, AES.block_size))
# 解密
cipher2 = AES.new(key, AES.MODE_CBC, iv)
decrypted = unpad(cipher2.decrypt(ciphertext), AES.block_size)
print(decrypted.decode()) # 密钥边界设计实战
注意: IV 不要重复使用!CBC 模式下 IV 需要随机生成,且每次加密用新 IV,否则会被攻击者用来恢复明文。我在项目中见过同事把 IV 写死在代码里,差点出事。
2.2 非对称加密:公钥私钥两把锁
非对称加密,一对密钥:公钥公开,私钥保密。公钥加密的,只有对应的私钥能解;反过来,私钥签名,公钥验证。
你想想看,如果两个人初次通信,怎么安全地交换对称密钥?用非对称加密来传输密钥就解决了。这就是密钥分发的经典场景。
| 特性 | 对称加密 | 非对称加密 |
|---|---|---|
| 速度 | 快(硬件加速可达数 Gbps) | 慢(适合小数据) |
| 密钥数量 | 每对通信双方需要单独密钥(N 方需 N(N-1)/2) | 每人一对密钥即可 |
| 典型用法 | 加密大块数据 | 密钥交换、数字签名 |
| 安全性依赖 | 密钥保密 | 私钥保密 + 数学难题 |
RSA 的密钥生成过程我简单写一下,让你有手感:
from Crypto.PublicKey import RSA
# 生成 2048 位 RSA 密钥对
key = RSA.generate(2048)
private_key = key.export_key()
public_key = key.publickey().export_key()
print(private_key.decode()[:100] + "...") # 打印前 100 字符示意
经验: 我个人习惯在非对称加密中优先使用 ECC(椭圆曲线),比如 ECDSA 或 Ed25519。同样的安全强度下,ECC 的密钥比 RSA 短很多,性能更好。但生态兼容性需要注意,有些老旧系统只认 RSA。
这里有个避坑点。我曾经在金融项目里用 RSA-OAEP 加密,结果忘了检查密钥对的匹配性。上线后有一部分数据用错了公钥,恢复不了。后来我强制在存储前做一次加解密自检。
2.3 哈希函数:不可逆的数字指纹
哈希函数不是加密算法,它没有密钥。输入任意长度,输出固定长度(比如 SHA-256 输出 256 位)。关键性质:
- 单向性:从哈希值几乎不可逆推原消息。
- 抗碰撞性:极难找到两个不同输入产生相同哈希值。
- 雪崩效应:输入改一个比特,输出翻转一半以上。
哈希在密钥边界设计里经常用在几个地方:
- 完整性校验:验证数据在传输或存储中是否被篡改。
- 口令存储:服务端不存明文密码,存哈希值。注意要用加盐(salt)的慢哈希(如 bcrypt、Argon2)。
- 密钥派生:通过 PBKDF2、HKDF 从密码学上安全的种子派生出多个子密钥。
看个简单的 SHA-256 例子:
import hashlib
data = "密钥边界设计"
hash_obj = hashlib.sha256(data.encode())
print(hash_obj.hexdigest())
# 输出类似 d2e8...(64 位十六进制)
安全警告: 不要直接用 MD5 或 SHA-1!它们已经不再安全,可在毫秒级内被碰撞攻击。即使只用做校验,也建议用 SHA-256 或更高。
我参与过一个审计系统,用了 SHA-1 做日志完整性校验。后来安全团队扫描发现风险,我们全部替换为 SHA-256。那段时间加班调接口,真是教训。
2.4 混合加密:三者协作
实际项目里不会只用一种,而是混合使用。典型流程:
- 发送方用 非对称加密 传递一次性的会话密钥。
- 双方用这个会话密钥做 对称加密 加密业务数据。
- 同时用 哈希函数 计算数据摘要,实现完整性校验。
HTTPS 的 TLS 握手就是这么干的。你想想看,没有哈希保证完整性,攻击者可以篡改密文然后在应用层搞破坏。
一句话记住: 对称加密负责快,非对称加密负责安全分发,哈希负责验真。密钥边界设计就是管好这三把钥匙。