2、密钥生成与分发追溯

密钥这东西,说白了就是安全体系的命根子。你审计的时候,如果连密钥怎么生出来的、怎么发出去的都说不清楚,那后面的追溯全是空谈。我个人习惯,拿到一个系统的密钥管理方案,先看两件事:生成策略够不够随机,分发协议有没有防篡改。

2.1 密钥生成策略

密钥生成不是随便敲几个随机数就完事的。我见过不少项目,开发图省事,直接用 rand() 或者 Math.random() 来生成密钥。嗯,这种密钥在审计面前基本等于裸奔。

⚠️ 常见坑:伪随机数生成器(PRNG)如果种子可预测,生成的密钥序列就能被复现。我曾经审计过一个金融系统,他们用系统时间戳当种子,结果攻击者只要知道业务发生时间,就能算出所有会话密钥。

正确的做法,必须使用密码学安全的随机数生成器(CSPRNG)。比如 Linux 下的 /dev/urandom,或者 OpenSSL 的 RAND_bytes()。审计时要重点检查:

  • 随机源:是否依赖硬件熵源?有没有 fallback 到弱随机?
  • 生成算法:是直接用随机数,还是经过 KDF(密钥派生函数)处理?
  • 密钥长度:对称密钥至少 256 位,RSA 至少 2048 位,ECC 至少 256 位。
  • 生命周期:密钥有没有过期时间?过期后怎么轮换?
密钥类型 推荐算法 最小长度 生成方式
对称密钥 AES-256 256 bit CSPRNG 直接生成
非对称密钥 RSA / ECDSA 2048 bit / 256 bit 专用密钥生成算法
会话密钥 DH / ECDH 256 bit 密钥协商协议
派生密钥 HKDF / PBKDF2 取决于主密钥 KDF 从主密钥派生
💡 审计小技巧:检查密钥生成日志时,重点看有没有记录「随机源类型」和「熵池状态」。如果日志里只有「生成成功」四个字,那基本等于没记。

2.2 安全分发协议

密钥生成好了,怎么安全地送到对方手里?这是另一个大坑。直接通过网络传输明文密钥?那跟把密码写在明信片上没区别。

实际生产环境里,最常用的就是 Diffie-Hellman 密钥交换协议。它的核心思想是:双方在不安全的信道上,通过数学计算协商出一个共享密钥,即使中间人偷听了所有通信,也算不出这个密钥。

我简单说一下 DH 的流程,你审计的时候要对照着看:

  1. 参数协商:双方约定一个大素数 p 和生成元 g。
  2. 生成私钥:各自生成一个随机数作为私钥(a 和 b)。
  3. 计算公钥:A = g^a mod p,B = g^b mod p。
  4. 交换公钥:把 A 和 B 发给对方。
  5. 计算共享密钥:A 方计算 B^a mod p,B 方计算 A^b mod p,结果相同。
🔑 关键点:共享密钥从未在网络上传输!传输的只是公钥 A 和 B。攻击者即使拿到 A 和 B,要算出 a 或 b,需要解离散对数问题——这在计算上是不可行的。

但是,DH 有一个致命弱点:中间人攻击。攻击者可以冒充双方,各自建立两个 DH 会话。你想想看,如果 A 和 B 没有验证对方的身份,那密钥其实是被攻击者控制的。

解决办法?用 认证的密钥交换协议。比如:

  • STS 协议:在 DH 交换过程中加入数字签名,验证双方身份。
  • ECDHE + 证书:TLS 1.3 的做法,用椭圆曲线 DH 临时密钥,配合 X.509 证书做身份认证。
  • 预共享密钥(PSK):双方事先有一个共享密钥,用它来加密 DH 参数。
⚠️ 避坑指南:我曾经审计过一个 IoT 平台,他们用了 DH 但没有做身份认证。结果攻击者伪造了一个设备,跟服务器建立了密钥,然后冒充服务器跟真实设备建立另一个密钥。所有数据都被中间人解密了。后来我建议他们加上 ECDSA 签名,才堵住这个漏洞。

2.3 日志记录要点

密钥生成和分发的日志,是审计追溯的核心证据。但很多系统的日志,要么记不全,要么记了也没用。我总结了几条必须记录的要点:

阶段 必须记录的字段 说明
密钥生成 时间戳、密钥ID、算法、长度、随机源类型、熵池状态、操作人/模块 记录随机源是为了后续审计随机性质量
密钥分发 时间戳、源身份、目标身份、协议类型、参数哈希、是否使用证书 参数哈希用于验证协议是否被篡改
密钥接收 时间戳、接收方身份、密钥指纹、验证结果 密钥指纹用于确认收到的密钥与发送的一致
密钥激活 时间戳、密钥ID、生效时间、失效时间、使用范围 明确密钥的生命周期状态
💡 个人经验:日志里一定要加一个「事件ID」字段,把生成、分发、接收、激活这几个环节串起来。这样你追溯的时候,一条命令就能查出整个密钥的完整生命周期。我见过最差的日志,每个环节各自记各自的,连个关联字段都没有,查起来简直要命。

另外,日志本身也要防篡改。建议使用 区块链式日志结构,每条日志包含前一条的哈希值。或者至少用 HMAC 对日志条目做完整性校验。否则攻击者删改日志,你根本发现不了。

嗯,这里还要注意一个细节:日志里绝对不能记录密钥本身。只记录密钥的哈希值或指纹。密钥明文一旦落入日志,那整个安全体系就崩了。

密钥生成与分发追溯流程图 密钥生成 CSPRNG + KDF 日志记录 密钥ID / 算法 / 随机源 密钥分发 DH / ECDHE + 证书 日志记录 源/目标身份 / 参数哈希 密钥接收 验证指纹 / 完整性 日志记录 接收方 / 验证结果 密钥激活 生效时间 / 使用范围 日志记录 事件ID / 生命周期状态 ⚠️ 关键审计点 日志必须包含事件ID 串联生成→分发→接收→激活

最后说一句,密钥追溯不是事后诸葛亮。你得在设计阶段就把日志埋好,把事件ID串好。等出了安全事件再回头补日志,那已经来不及了。我每次做审计,第一件事就是看密钥日志的完整性——如果日志本身都不可信,那整个审计报告就是废纸。