加密算法基础

这一章,我们来啃一啃加密算法这块硬骨头。你可能会想:“不就是把数据变乱吗?用个AES不就行了?”——嗯,实际落地时坑不少。我这些年做对象存储加密SDK,见过太多因为选错算法、配错参数导致的性能灾难。所以咱们得把对称加密、非对称加密、密钥协商这三板斧的原理和坑点都捋清楚。

对称加密:AES

AES(Advanced Encryption Standard)是最主流的对称加密算法。说白了,就是加密和解密用同一把钥匙。速度快,适合加密大块数据——比如你的图片、视频文件。

我习惯用pycryptodome库做原型验证。AES核心参数就三个:密钥长度、工作模式、初始向量(IV)。密钥长度选128、192或256位,256更安全但慢一丢丢;模式我首推GCM,因为它自带认证,能防篡改。你还真别说,有一次我在项目中图省事用了ECB模式,结果密文块重复特征明显,被安全审计怼了回来…从那以后我再也不敢偷懒。

下面是一个AES-GCM加密/解密的Python示例:

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes

key = get_random_bytes(32)      # AES-256
nonce = get_random_bytes(12)    # GCM推荐12字节nonce
plaintext = b"Hello, Object Storage!"

cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
ciphertext, tag = cipher.encrypt_and_digest(plaintext)

# 解密
cipher_dec = AES.new(key, AES.MODE_GCM, nonce=nonce)
data = cipher_dec.decrypt_and_verify(ciphertext, tag)
print(data.decode())            # 输出明文

工作中最常对比的模式如下表,方便你选型时参考:

模式是否需要IV并行解密认证典型场景
ECB否是无只适合短固定数据(❌ 不推荐)
CBC是否无传统文件加密(需配合HMAC)
GCM是(nonce)是有网络传输、对象存储(✅ 推荐)
CTR是是无流式加密

我的习惯:在对象存储场景,直接用AES-256-GCM,128位nonce。省心,还能应对合规审计。

非对称加密:RSA

AES快,但怎么安全地把密钥传给对方?这就是RSA登场的原因。RSA用一对密钥:公钥加密,私钥解密。反过来还能做数字签名。

项目里RSA最常用的地方就是加密AES密钥。比如客户端生成一个AES密钥,用服务端公钥加密后上传,服务端用私钥解密得到AES密钥,后续用AES加密数据。这叫“混合加密”,既安全又高效。

我曾在一次联调中踩过RSA长度的坑:当时用了512位密钥,本地跑飞快,一上线就被安全扫描报弱密钥。后来强制升级到2048位,性能下降不少,但合规是硬指标。我建议你现在就直接用2048或4096位。

RSA加密代码(使用OAEP填充):

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP

# 生成密钥对
key = RSA.generate(2048)
public_key = key.publickey()

# 加密AES密钥
aes_key = b"this-is-a-32-byte-key-12345"
cipher_rsa = PKCS1_OAEP.new(public_key)
encrypted_key = cipher_rsa.encrypt(aes_key)

# 解密
cipher_rsa_dec = PKCS1_OAEP.new(key)
decrypted_key = cipher_rsa_dec.decrypt(encrypted_key)
print(decrypted_key == aes_key)  # True

对称和非对称的核心区别,我整理成了一张对比表:

特性AESRSA
密钥单一密钥公钥/私钥对
速度快(GB/s级别)慢(MB/s级别)
适合加密数据量任意大小有限(≈密钥长度)
用途数据加密密钥交换、签名

注意:RSA直接加密大数据会失败(2048位RSA最多加密256字节)。所以实际方案永远是“RSA加密AES密钥,AES加密业务数据”。

密钥协商

知道了AES和RSA,你可能有一个问题:如果客户端和服务端事先没有共享密钥,怎么安全地建立对称密钥?密钥协商就是来解决这个问题的。最经典的是Diffie-Hellman(DH)协议,它让双方在不安全的信道上共同算出同一个秘密数,而不泄露秘密本身。

在对象存储加密SDK里,我常常用ECDH(基于椭圆曲线的DH)来协商临时AES密钥。每个会话生成一次密钥对,计算共享密钥后立即销毁私钥——这叫“前向安全性”。就算服务器私钥泄露,历史数据也解不开。

我举个例子(简化版ECDH):

from Crypto.PublicKey import ECC
from Crypto.Protocol import DH

# 客户端生成密钥对
client_key = ECC.generate(curve='P-256')
# 服务端生成密钥对
server_key = ECC.generate(curve='P-256')

# 计算共享密钥(双方得到的值相同)
client_shared = DH.key_agreement(
    static_priv=client_key,
    static_pub=server_key.public_key()
)
server_shared = DH.key_agreement(
    static_priv=server_key,
    static_pub=client_key.public_key()
)
print(client_shared == server_shared)  # True

注意这个共享密钥不能直接当AES密钥用,通常需要再通过KDF(如HKDF)导出。我曾经在实现时忘了做这一步,直接用原始字节当密钥,结果被安全工具检测出不足熵…嗯,教训深刻。

核心逻辑梳理:

  • 对称加密(AES)负责数据加密,速度快。
  • 非对称加密(RSA/ECC)负责加密AES密钥或数字签名,安全性高。
  • 密钥协商(DH/ECDH)让双方在无预先密钥的情况下安全地得到共享秘密。

把这三种算法的关系画成一个图,会直观很多。下面这张SVG图展示了它们在对象存储加密中的典型协作流程:

加密算法协作图 加密算法在对象存储加密中的协作 对称加密 (AES) 加密对象数据 密钥: 128/256位 非对称加密 (RSA/ECC) 加密AES密钥 密钥: 2048/4096位 密钥协商 (DH/ECDH) 安全交换共享秘密 前向安全性 生成AES密钥 使用RSA/ECC签名认证 🔑 混合加密流程简述 1. 客户端与服务端通过DH协商临时AES密钥 2. 客户端用AES加密数据,用RSA公钥加密AES密钥,上传

你看,整个流程并不复杂。对称加密负责数据搬砖,非对称加密负责保护钥匙,密钥协商负责安全发钥匙——三者缺一不可。搞懂这些基础,后面调SDK参数、做性能优化时,你就能知道该在哪个环节下功夫。