第3章 加密技术基础:对称加密、非对称加密、哈希、AEAD

做审计日志系统,逃不开一个话题:加密。

你想想看,日志里可能记录着用户操作、敏感数据变更、甚至密钥轮换记录。如果这些内容以明文存储,那审计系统本身就变成了最大的安全隐患。

所以,搞明白四种核心加密技术,是咱们后续做索引和查询优化的地基。这一章,我把它们掰开了讲,结合我在审计项目里踩过的坑,给你说透。

加密技术基础全景 加密技术基础 四大核心技术 对称加密 AES / DES 非对称加密 RSA / ECC 哈希函数 SHA-256 / SM3 AEAD AES-GCM / ChaCha20 批量加密 性能优先 密钥交换 数字签名 完整性校验 链式哈希 认证加密 抗篡改 核心要点 审计日志场景中,AEAD 兼顾机密性与完整性,是首选方案 哈希用于日志指纹链,非对称加密用于签名验签

3.1 对称加密:又快又简单,但密钥怎么管?

对称加密,说白了就是加密和解密用同一把钥匙。常见的算法有 AES、DES、SM4。

它的优点就一个字:快。硬件加速后,AES-256 在普通服务器上能达到 GB 级吞吐。所以,审计日志里的大块内容——比如完整的请求/响应体——我习惯用对称加密来搞定。

我的习惯:日志正文用 AES-256-GCM 加密(这就是 AEAD 的一种),既保证速度又带认证。纯 AES-CBC 模式我已经很少用了,原因下面会讲。

但对称加密有个硬伤——密钥分发。你用同一把钥匙加密所有日志,那这把钥匙一旦泄露,全部日志就被看光了。

我在项目里遇到过一件事:某个团队把 AES 密钥硬编码在配置中心,结果配置中心被扫出来一个弱密码。嗯,从那以后我定了一条规矩——对称密钥必须定期轮换,并且用非对称加密来传输。

  • 优点:计算开销小,适合海量日志加密
  • 缺点:密钥管理复杂,需要配套的密钥生命周期系统
  • 审计场景:加密日志正文、敏感字段(如 IP、用户 ID)

3.2 非对称加密:公钥私钥,各司其职

非对称加密,密钥成对出现:公钥加密,私钥解密;或者私钥签名,公钥验签。常用算法有 RSA、ECC(SM2 是国密版本)。

速度上,它比对称加密慢两到三个数量级。所以没人用它来加密大段日志。那它在审计系统里干嘛用?两件事:数字签名 和 密钥交换。

审计日志的不可否认性,靠的就是非对称签名。

每条日志落盘前,用私钥算一个签名。后续审计时,只要公钥能验过签名,就能证明这条日志没被篡改过,而且确实是那个节点产生的。这招在合规审计里几乎是必选项。

我曾经遇到过一个坑:有个系统用 RSA-1024 做签名,部署了三年才发现密钥强度已经不满足监管要求。换到 RSA-2048 或者 ECC P-256,花了整整两周的迁移时间。所以,我建议一开始就用 ECC,密钥短、性能好、未来十年都扛得住。

  • 签名:每条日志追加一个签名,用于防篡改和溯源
  • 密钥交换:用非对称加密传输对称密钥,解决密钥分发问题
  • 性能注意:签名验签频率高的话,建议用 ECC 或 SM2,降低 CPU 开销
注意:非对称加密不能替代哈希完整性校验。签名只能验证「谁签的」,不能验证「内容本身是否完整」。这两者是互补关系,不是替代关系。

3.3 哈希函数:不可逆的指纹

哈希函数把任意长度的数据压缩成固定长度的摘要。常见的算法有 SHA-256、SHA-3、SM3。哈希的特点是单向且抗碰撞——你没法从摘要反推出原文,也很难找到两个不同的输入产生相同的摘要。

在审计日志里,哈希有两个经典用途:

  1. 日志指纹链:每条日志的哈希包含上一条的哈希,形成链式结构。任何人想篡改中间某条日志,都得把后面的哈希全改一遍,成本极高。
  2. 完整性校验:定期对日志文件计算哈希,跟存档值比对,确认文件没有被静默损坏或篡改。
一个小技巧:如果日志量太大,全量哈希链的性能扛不住,可以做「间隔锚点哈希」——每 1000 条日志算一个链式哈希锚点,中间用 Merkle Tree 组织。这样查询某条日志的完整性时,只需要计算局部的 Merkle 证明,而不是遍历整个链。

我曾经踩过一个坑:用 MD5 做日志指纹。当时觉得日志只是内部用,结果被安全审计扫出来,说 MD5 已经能被碰撞攻击。全量重新哈希一遍,几百万条日志跑了半天。从那以后,我不管什么场景,哈希一律用 SHA-256 起步。

3.4 AEAD:一步到位,省心省力

AEAD(Authenticated Encryption with Associated Data)是「认证加密」的缩写。它把机密性和完整性合在一个算法里,一步搞定。

常见的 AEAD 方案有 AES-256-GCM、ChaCha20-Poly1305。你想想看,以前我们要先加密再用 HMAC 做认证,两个步骤容易出错——比如有人忘了做 HMAC,或者 nonce 重复使用。AEAD 直接消灭了这类问题。

我个人强烈建议:所有审计日志的加密,优先用 AEAD。理由很简单——它同时保证「别人看不懂」和「别人改不了」。而且,大部分现代 CPU 都对 GCM 模式做了硬件加速,性能几乎不输纯对称加密。

下面是一个用 Python 实现 AES-256-GCM 加密日志的示例,也是我项目中一直在用的模板:

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

def encrypt_log_entry(key: bytes, log_data: bytes, associated_data: bytes = b"") -> bytes:
    # 生成随机 nonce,每次加密必须不同
    nonce = os.urandom(12)
    aead = AESGCM(key)
    # 加密并认证,associated_data 参与认证但不加密
    ciphertext = aead.encrypt(nonce, log_data, associated_data)
    # 存储格式:nonce + 密文,方便解密时提取
    return nonce + ciphertext

def decrypt_log_entry(key: bytes, encrypted: bytes, associated_data: bytes = b"") -> bytes:
    nonce = encrypted[:12]
    ciphertext = encrypted[12:]
    aead = AESGCM(key)
    return aead.decrypt(nonce, ciphertext, associated_data)

# 使用示例
key = AESGCM.generate_key(bit_length=256)
log = b"user=admin action=delete_file target=config.yaml ts=2025-01-15T10:00:00Z"
encrypted = encrypt_log_entry(key, log, b"audit_log_v1")
decrypted = decrypt_log_entry(key, encrypted, b"audit_log_v1")
print(decrypted.decode())
警告:AEAD 的 nonce 不能重复使用。同一个 key 下,nonce 重复会直接导致认证密钥泄露。我见过一次事故——开发同学用时间戳秒级精度做 nonce,同一秒内两条日志 nonce 碰撞,整个加密方案报废。修复方案:用 12 字节随机数,或者用单调递增计数器 + 足够长的 nonce。

3.5 四种技术对比

到这里,四种技术的定位应该清楚了。我整理了一个对比表格,方便你快速参考:

技术 核心能力 审计日志用途 性能特点 常见算法
对称加密 机密性 加密日志正文 极快,硬件加速 AES-256, SM4
非对称加密 签名 / 密钥交换 数字签名、传输对称密钥 慢,适合小数据量 ECC P-256, RSA-2048, SM2
哈希函数 完整性 / 指纹 日志链式校验、文件完整性 快,可并行 SHA-256, SHA-3, SM3
AEAD 机密性 + 完整性 加密+认证一步完成(推荐) 较快,GCM 有硬件加速 AES-256-GCM, ChaCha20-Poly1305

我给你的选型建议:

  • 日志正文加密 → AEAD(AES-256-GCM 或 ChaCha20-Poly1305)
  • 日志签名验签 → 非对称加密(ECC P-256 优先)
  • 日志指纹链 → 哈希(SHA-256,配合间隔锚点)
  • 密钥传输 → 非对称加密保护对称密钥

四种技术各有所长,但实际项目中往往是组合使用。比如一条审计日志:用 AEAD 加密正文保证机密性和完整性,再对整条日志(含元数据)做一次 ECC 签名,最后把哈希锚点写入区块链或持久化存储。你看,一环扣一环,每种技术都在合适的位置发挥作用。