加密算法实战:AES、RSA、ECC 原理与 Python 实现
加密算法这东西,听起来很玄乎,其实说白了就是两件事:把数据变成别人看不懂的乱码,以及把乱码变回来。我最早在密钥边界项目里选加密算法时,真是踩了不少坑。今天咱们就把 AES、RSA 和 ECC 这三个最常用的算法拎出来,逐个拆开揉碎,看看它们到底怎么干活的,以及怎么用 Python 实打实地写出来。
对称加密:AES
AES 是目前最主流的对称加密算法。什么叫对称?加密和解密用同一个密钥。你想想看,就像你锁门用一把钥匙,开门也用同一把。AES 支持 128、192、256 三种密钥长度,目前 128 位已经够用,但我个人习惯直接用 256 位——多出来的几微秒运算时间,换来的安全性提升完全值得。
AES 加密过程分好几轮(10/12/14 轮对应不同密钥长度),每轮做字节替换、行移位、列混合和轮密钥加。听着复杂?别怕,Python 已经有现成的 pycryptodome 库,几行代码就能搞定。
重要提醒:AES 有五种工作模式(ECB、CBC、CFB、OFB、CTR)。ECB 模式不安全,同一个明文块会生成相同密文块,千万别在生产环境用。我接过一个项目,就因为用了 ECB,攻击者从密文里直接猜出了用户头像轮廓。
# AES-CBC 加密与解密示例
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import os
key = os.urandom(16) # 128位密钥
iv = os.urandom(16) # 初始向量
def encrypt(plaintext):
cipher = AES.new(key, AES.MODE_CBC, iv)
ct_bytes = cipher.encrypt(pad(plaintext.encode(), AES.block_size))
return ct_bytes
def decrypt(ciphertext):
cipher = AES.new(key, AES.MODE_CBC, iv)
pt = unpad(cipher.decrypt(ciphertext), AES.block_size)
return pt.decode()
data = "密钥边界项目需要保护敏感配置"
enc = encrypt(data)
dec = decrypt(enc)
print(f"对称加密成功:{dec}")
| AES 模式 | 特点 | 适用场景 |
|---|---|---|
| CBC | 需要 IV,密文与前一块相关 | 文件加密、传输数据 |
| GCM | 认证加密,防篡改 | 网络协议、API 认证 |
| CTR | 并行度高,可随机访问 | 磁盘加密、流媒体 |
| ECB | 不安全 | 仅用于学习,切勿用于生产 |
避坑指南:我曾经在密钥管理模块里把 IV 硬编码写死了,结果测试环境泄露了固定 IV,导致同一个密钥下所有密文的前16字节都能被还原。务必使用随机 IV,且每次加密都要重新生成。
非对称加密:RSA
RSA 是非对称加密的鼻祖,用一对密钥:公钥加密,私钥解密。公钥可以公开,私钥必须保密。AES 虽然快,但密钥分发是个大麻烦——你把 AES 密钥发出去的时候就可能被人截获。RSA 正好解决这个问题:对方用你的公钥加密一个临时 AES 密钥,你收到后用私钥解密,后面的数据再用 AES 加解密。这叫“混合加密体系”,我在密钥边界项目里就是这样搭的。
RSA 基于大整数分解难题,密钥越长越安全。1024 位已经被破解,现在最小建议 2048 位。不过 RSA 加密有个坑:明文长度不能超过密钥长度减去填充长度。所以实际中我们绝不拿 RSA 直接加密大数据,只用来加密 AES 密钥或哈希值。
# RSA 密钥生成与加解密
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import binascii
# 生成 2048 位密钥对
key = RSA.generate(2048)
private_key = key.export_key()
public_key = key.publickey().export_key()
print(f"私钥长度: {len(private_key)} 字节")
print(f"公钥长度: {len(public_key)} 字节")
# 加密小数据(不超过190字节)
msg = b"AES-256密钥: f4k3k3y12345678"
cipher = PKCS1_OAEP.new(RSA.import_key(public_key))
ciphertext = cipher.encrypt(msg)
# 解密
cipher_dec = PKCS1_OAEP.new(RSA.import_key(private_key))
plaintext = cipher_dec.decrypt(ciphertext)
print(f"RSA解密成功: {plaintext}")
个人经验:RSA 加解密速度慢,每秒钟只能处理几百次 2048 位操作。如果你需要频繁握手,建议配合 ECDH 或 ECC 来交换会话密钥,减少 RSA 的使用频次。
椭圆曲线密码:ECC
ECC 是后起之秀。同样安全强度下,ECC 的密钥长度比 RSA 短得多——256 位的 ECC 密钥相当于 3072 位的 RSA。这就意味着更小的存储、更快的运算、更低功耗。我参与的一个物联网密钥边界项目,设备内存只有 64KB,RSA 根本塞不下,换成 ECC(基于 secp256r1 曲线)后,密钥交换效率提升了几十倍。
ECC 不直接做加解密,更多用于数字签名(ECDSA)和密钥交换(ECDH)。但也能做加密,只是算法复杂些。实际项目中我推荐直接用 ECDH 协商临时 AES 密钥,既安全又高效。
# ECC 密钥生成与 ECDH 密钥交换
from Crypto.PublicKey import ECC
from Crypto.Protocol.KDF import HKDF
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
import os
# 双方各自生成密钥对
alice_key = ECC.generate(curve='P-256')
bob_key = ECC.generate(curve='P-256')
# 交换公钥,计算共享点
shared_point_alice = alice_key.d * bob_key.pointQ
shared_point_bob = bob_key.d * alice_key.pointQ
# 确保一致
assert shared_point_alice == shared_point_bob
# 将共享点的x坐标转为对称密钥
shared_secret = int(shared_point_alice.x).to_bytes(32, 'big')
aes_key = HKDF(shared_secret, 16, salt=b'keyborder', info=b'ecdh', hashmod=SHA256)
print(f"ECDH协商的AES密钥: {aes_key.hex()}")
| 特性 | AES (对称) | RSA (非对称) | ECC (非对称) |
|---|---|---|---|
| 密钥长度 | 128-256 bit | 2048-4096 bit | 224-521 bit |
| 加密速度 | 极快 (GB/s) | 慢 (MB/s) | 较快 (百MB/s) |
| 主要用途 | 数据加密 | 密钥加密、签名 | 密钥交换、签名 |
| 适合场景 | 大量数据传输 | 小数据、证书 | 移动/物联网设备 |
三种算法如何协同工作
实际项目里没人只用一种加密。我设计的密钥边界项目方案是:ECC 做密钥交换,协商出一个临时 AES 密钥;AES 做实际数据加密;如果需要对关键操作(比如更新配置)进行数字签名,再用 RSA 或 ECDSA。这样各取所长,安全又高效。
实战中的选择建议
- 数据加密:首选 AES-256-GCM,自带认证防篡改。
- 密钥交换:能用 ECDH 就别用 RSA 直接加密密钥,效率高一个数量级。
- 数字签名:RSA 兼容性好,ECC 签名短且快。如果你对接的都是现代系统,果断 ECDSA;如果需要跟旧系统互通,选 RSA PKCS#1 v1.5。
- 密钥长度:AES 选 256 位,RSA 选 2048 位以上,ECC 选 P-256(secp256r1)。
曾经踩过的坑:我在一个项目中用了 Python 标准库的 rsa 模块做签名,结果发现它默认使用 PKCS#1 v1.5 填充,这个填充方式已被证明存在中间人攻击风险。后来全换成了 PKCS1_OAEP 和 PSS。记住:能用 OAEP 就用 OAEP,签名用 PSS,别图省事用旧版本。
小结一下
AES 是对称加密的王者,快但密钥分发麻烦;RSA 是经典非对称,慢但公钥基础设施完善;ECC 是现代新贵,短密钥高安全。在密钥边界项目里,我通常把这三者组合使用:用 ECC 协商临时 AES 密钥,用 AES 加密大批量数据,再用 RSA 或 ECDSA 对关键操作签名。你动手写代码的时候,记得先装 pycryptodome,然后按我刚才的示例一步步试。嗯,等你跑通第一个加密、解密流程,你会发现加密其实没那么神秘——说白了就是几个数学公式加上一些编码技巧的产物。但选对算法、用对模式,就是安全工程的真本事了。