3. 加密基础知识回顾

说实话,我在做对象存储加密SDK对接时,发现很多问题根源都在基础概念没吃透。尤其是刚接触加密的同学,经常把对称加密和非对称加密混着用,跑出来的密文自己都解不开。这一节我们把这些基础好好捋一捋。

3.1 对称加密 vs 非对称加密:核心区别

这两个概念,说白了就是「一把钥匙」和「两把钥匙」的区别。

对称加密:加密和解密用同一把密钥。你想想看,就像你用一把锁锁上箱子,同一把钥匙又能打开。速度快,适合加密大文件。但问题来了——怎么把密钥安全地交给对方?

非对称加密:有一对密钥——公钥和私钥。公钥公开,私钥自己藏好。别人用你的公钥加密数据,只有你能用私钥解开。速度慢,但解决了密钥分发难题。

我记得刚开始做加密时,总觉得非对称加密更安全,所有场景都想用RSA。结果有一次加密一个几百MB的文件,跑了好几分钟都没出来……后来才意识到,实际项目中多用「混合加密」:用RSA加密AES的密钥,用AES加密真正的数据。

特性 对称加密 非对称加密
密钥数量 1 个(共享密钥) 2 个(公钥 + 私钥)
速度 快(硬件加速支持好) 慢(数学运算复杂)
典型算法 AES, ChaCha20 RSA, ECC
适用场景 大量数据加密 密钥交换、数字签名
密钥分发 困难(需要安全通道) 简单(公钥可公开)
注意:千万不要用ECB模式加密结构化数据(比如JSON、图片头部)。相同的明文块会产生相同的密文块,很容易被识别出规律。我在项目中见过有人这么干,结果安全审计直接亮了红灯。

3.2 AES:对称加密的工业标准

AES(Advanced Encryption Standard)是目前最主流的对称加密算法,支持128、192、256位密钥。我建议你在对象存储加密场景中优先使用 AES-256-GCM 模式,它同时提供加密和完整性校验。

下面是一个使用 Python cryptography 库进行 AES-GCM 加密解密的例子:

from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os

# 生成 256 位密钥
key = AESGCM.generate_key(bit_length=256)
aesgcm = AESGCM(key)

# 生成随机 nonce(12 字节)
nonce = os.urandom(12)

# 加密
plaintext = b"Hello, Object Storage!"
ciphertext = aesgcm.encrypt(nonce, plaintext, None)

# 解密
decrypted = aesgcm.decrypt(nonce, ciphertext, None)
print(decrypted.decode())  # 输出: Hello, Object Storage!
我的习惯:nonce 每次加密都必须重新生成,不能重复使用相同的 nonce 和密钥组合,否则加密就失效了。我通常把 nonce 直接拼在密文前面,解密时再截取出来。

3.3 RSA:最经典的非对称加密

RSA 的名字来自三位发明者的姓氏首字母。它的安全性基于大整数分解的数学难题——用两张大素数生成密钥很容易,但从公钥反推私钥几乎不可能。

我刚开始做加密时,总觉得密钥越长越安全,一上来就生成 4096 位的 RSA 密钥。结果生成一次等了好几分钟,加密小数据也慢得离谱。后来才学会根据场景选择:2048 位对大多数场景已经足够安全,而且性能尚可。

from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes

# 生成 2048 位密钥对
private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048
)
public_key = private_key.public_key()

# 公钥加密(只能加密少量数据)
message = b"AES Key: 1234567890abcdef"
ciphertext = public_key.encrypt(
    message,
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)

# 私钥解密
plaintext = private_key.decrypt(
    ciphertext,
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)
print(plaintext.decode())
避坑指南:我曾经直接用 RSA 加密大文件,结果抛了异常——RSA 能加密的数据长度受密钥位数限制(2048 位密钥最多加密 190 字节左右)。正确的做法是「混合加密」:用 RSA 加密 AES 的密钥,用 AES 加密真正的数据。

3.4 哈希函数:数据的「指纹」

哈希函数能把任意长度的数据,计算成一个固定长度的摘要。关键特性是:不可逆——从摘要无法还原原文。而且输入稍微改一点,摘要就完全不一样。

你想想看,这就像给数据打了一个「指纹」。在对象存储里,我常用它来验证文件有没有被篡改——上传时计算哈希,下载后再算一次,对比就知道文件是否完整。

常见的哈希算法有 MD5(已不推荐)、SHA-1(已不推荐)、SHA-256、SHA-3 等。目前在对象存储场景中,SHA-256 是最主流的选择。

import hashlib

# 计算文件的 SHA-256 哈希
def sha256_file(filepath):
    sha256 = hashlib.sha256()
    with open(filepath, 'rb') as f:
        # 分块读取,避免大文件占用太多内存
        for chunk in iter(lambda: f.read(8192), b''):
            sha256.update(chunk)
    return sha256.hexdigest()

# 示例
digest = sha256_file('example.dat')
print(f'SHA-256: {digest}')
一个坑:我曾用 MD5 做文件完整性校验,结果被人用「哈希碰撞」手法伪造了文件——两个不同文件算出了同一个 MD5 值。从那以后我全换成了 SHA-256。虽然 SHA-256 理论上也有碰撞概率,但在工程实践中几乎可以忽略。

3.5 消息认证码:带密钥的哈希

哈希函数只能保证「数据没被改过」,但无法判断「数据是谁发的」——因为哈希算法是公开的,谁都能算。消息认证码(MAC)就是为了解决这个问题:在哈希计算中加入共享密钥,只有知道密钥的人才能生成和验证这个码。

最常见的实现是 HMAC(Hash-based Message Authentication Code),它把密钥和消息按特定方式混合后再做哈希。

import hmac
import hashlib

# 共享密钥(必须双方提前约定)
key = b'secret-object-storage-key'
message = b'important-file-content'

# 计算 HMAC-SHA256
hmac_obj = hmac.new(key, message, hashlib.sha256)
digest = hmac_obj.hexdigest()
print(f'HMAC-SHA256: {digest}')

# 验证方用相同的密钥和消息重新计算,对比结果
def verify_hmac(key, message, expected_hmac):
    computed = hmac.new(key, message, hashlib.sha256).hexdigest()
    # 使用 hmac.compare_digest 防止时序攻击
    return hmac.compare_digest(computed, expected_hmac)

is_valid = verify_hmac(key, message, digest)
print(f'验证通过: {is_valid}')
注意:对比 HMAC 时一定要用 hmac.compare_digest(),不要直接用 == 比较字符串。为什么?因为直接比较会在遇到第一个不同字符时就返回 False,攻击者可以根据响应时间推断出正确的 HMAC 值——这就是「时序攻击」。我踩过这个坑,后来被安全团队要求整改,印象深刻。

3.6 知识体系总览

上面讲的四个概念,构成了对象存储加密的核心基础。它们之间不是孤立的:对称加密和非对称加密经常配合使用(混合加密),消息认证码(HMAC)也建立在哈希函数之上。下面这张图帮你把关系理清楚。

加密基础知识体系 对称加密(AES) 密钥相同,加密解密用同一把 速度快,适合加密大量数据 需通过安全通道分发密钥 常用模式:GCM (加密+认证) 非对称加密(RSA) 密钥对:公钥加密,私钥解密 速度慢,适合加密小量数据 公钥可公开,无需分发私钥 常用位数:2048 / 4096 哈希函数(SHA-256) 不可逆,无法从摘要还原原文 固定长度输出(256位) 用于数据完整性校验 消息认证码(HMAC) 带密钥的哈希函数 同时验证完整性与真实性 防篡改 + 防伪造 混合加密:RSA 加密 AES 密钥 HMAC = 哈希函数 + 共享密钥

这张图把四个核心概念和它们之间的关系串在了一起。你可以看到:对称加密和非对称加密通过「混合加密」配合使用,哈希函数和消息认证码通过「HMAC」连在一起。在后续的章节中,我们会多次用到这些基础——尤其是 AES-GCM 和 HMAC-SHA256,它们是对象存储加密中最常用的两个工具。