第2章 对称加密与非对称加密基础
讲 KMS 之前,加密算法是绕不开的底子。我个人习惯先把这两个大类理清楚,免得后面谈密钥托管、证书链时听得云里雾里。说白了,对称加密和非对称加密就像锤子和扳手——场景不同,用法不同,但都要趁手。
2.1 对称加密:一把钥匙开一把锁
对称加密的核心理念很简单:加密和解密用同一把密钥。你拿这把锁锁上数据,再用同一把钥匙打开。效率高、吞吐量大,适合批量数据。
• 加解密都使用同一个 Secret Key
• 算法运算量小,硬件加速友好
• 密钥配送是最大难题——怎么安全地把钥匙交给对方?
我在项目里遇到过最典型的场景是:内部大数据管道传输,每天几十 TB 日志。用非对称加密?慢得离谱,CPU 直接爆。最后只能用 AES-256-GCM 对称加密,密钥通过 KMS 临时分发。
2.2 非对称加密:公钥私钥,各自分工
非对称加密就有意思了:一对钥匙——公钥公开、私钥私藏。公钥加密的数据只有私钥能解;反过来,私钥签名、公钥验签。它解决了密钥配送的老大难问题。
你想想看:世界上任何人都能用你的公钥给你发密文,只有你能解。这不正是 TLS 握手和数字证书的基础吗?
但代价也明显——计算量比对称加密高两三个数量级。所以实践中没人傻到用 RSA 去加密 4K 的视频流,一般是“非对称传对称密钥,对称密钥加密数据”。
2.3 常见算法速览表
下面这张表是我做选型时常用的参考。你可以存下来。
| 算法 | 类型 | 密钥长度(位) | 安全强度(等效于) | 典型场景 |
|---|---|---|---|---|
| AES | 对称 | 128 / 192 / 256 | 高(128位≈RSA-3072) | 数据加密、存储加密 |
| RSA | 非对称 | 2048 / 4096 / 8192 | 中(2048≈AES-112) | 密钥交换、数字签名 |
| ECC | 非对称 | 256 / 384 / 521 | 极高(256≈RSA-3072) | 证书签名、IoT、移动端 |
| SM4 | 对称 | 128 | 高(对标 AES-128) | 国密合规场景 |
| SM2 | 非对称 | 256 | 极高(对标 ECC-256) | 国密数字信封、签名 |
嗯,这里要注意:RSA 4096 比特虽然目前还安全,但性能下降明显。我在一个金融项目里硬扛过 RSA 4096 签名,TLS 握手慢了 30%——后来切到 ECDSA 才解决。
2.4 密钥长度与安全强度:别盲目堆位数
很多人以为密钥越长越安全,其实不然。安全强度说的是攻击者破解所需的“工作量”,不是单纯看位数。ECC 256 比特的安全强度就能打平 RSA 3072 比特。你想想看,少十倍的密钥长度,计算量也小得多。
我曾经在一个老系统里看到 RSA 8192 密钥,以为很安全。但实际攻击面根本不在算法强度——密钥存储方式才是瓶颈。私钥明文躺在磁盘上,算法再强也白搭。
我建议现代选型优先考虑:
• 对称:AES-256-GCM (兼顾速度和认证加密)
• 非对称:ECC P-384 或 X25519 (性能好、兼容性够)
• 量子安全前瞻:至少预留迁移到 ECC-521 或后量子算法的空间。
2.5 对称 vs 非对称:一张图看懂
2.6 混合加密:实战中的最优解
真正生产环境很少只用一种。TLS 就是典型:握手阶段用 ECDHE(非对称+DH)协商出临时对称密钥,然后数据传输用 AES-GCM。这叫“混合加密”,发挥各自长处。
我曾经在一个安全审计里看到某团队自己拼接 AES-ECB 和 RSA,结果因为 AES-ECB 的块独立特性导致严重的语义安全性漏洞。记住:用成熟的 TLS/KMS 封装,别造轮子。
我个人推荐至少掌握 AES-256-GCM 和 ECDSA P-384,这是当前云平台和证书服务的主流选型。你在做 KMS 集成、签发证书、配置密钥轮换时,这些算法会反复出现。
2.7 小经验总结
- 别被密钥长度吓唬:ECC 256 比特 > RSA 3072 比特,省带宽、省算力。
- 对称加密用 AEAD 模式(GCM/CCM):加密同时认证完整性,避免 padding oracle 攻击。
- 非对称用于“吻”而非“啃”:用来加密会话密钥或签名,不要直接加密大文件。
- 关注合规:国内政企场景优先考虑 SM2/SM4 国密系列,KMS 一般已支持。
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os
key = AESGCM.generate_key(bit_length=256) # 32字节
aesgcm = AESGCM(key)
nonce = os.urandom(12)
ciphertext = aesgcm.encrypt(nonce, b"Hello KMS", None)
plaintext = aesgcm.decrypt(nonce, ciphertext, None)
print(plaintext) # b"Hello KMS"
这章把对称和非对称的底子打牢了,后面讲密钥生成、证书签发时你就能一眼看穿它用的是哪类算法、密钥应该保存在哪。嗯,先消化一下,然后咱们再往下走。