密钥分发与协商

我一直觉得,密钥分发是整个加密系统里最容易被低估的一环。你写了个再强的算法,如果密钥分发环节出了纰漏,那等于把保险柜钥匙放在门口脚垫下面。说白了,我们聊的这套边界系统,核心问题就是:两边的密钥是怎么安全地到对方手里的?

这个问题的答案,基本分成三条路:Diffie-Hellman 密钥协商、公钥基础设施(PKI) 和 预共享密钥(PSK)。每条路都有它适用场景,也各有各的坑。下面我一个个说。

Diffie-Hellman 密钥协商

Diffie-Hellman 这东西,我特别喜欢它的优雅之处。它允许两方在不安全的信道上,通过交换一些公开信息,各自算出一个相同的共享密钥。整个过程,任何人都能监听你交换的数据,但他就是推不出最终的密钥。

基本原理是这样的:

  1. 双方约定一个大素数 p 和一个底数 g。
  2. 甲方选一个秘密数 a,计算 A = g^a mod p,发给乙方。
  3. 乙方选一个秘密数 b,计算 B = g^b mod p,发给甲方。
  4. 甲方用收到的乙方公值和自己的秘密数算:K = B^a mod p。
  5. 乙方用收到的甲方公值和自己的秘密数算:K = A^b mod p。
  6. 两边算出来的 K 是同一个值!

数学上有个难点:已知 g、p、A,想从中反推出 a,这叫离散对数问题,计算难度非常大。大到你等不起,所以它安全。

注意! 基础 DH 没有任何身份认证。我曾经在排查一个物联网项目的安全问题时就发现,攻击者完全可以伪造公钥,拦截双方通信。这就是著名的中间人攻击。你想想看,你和服务器握手,结果扮演服务器的其实是攻击者,他可以伪造自己的公钥给你,然后他自己跟真正的服务器再做一次 DH,双方都被他骗了。这样的场景下,你跟谁协商出了密钥都不知道!
解决方案: 必须结合签名(比如 ECDSA)或使用认证过的密钥交换协议(比如 SIGMA 族协议)来绑定身份。不要只用裸 DH。

为什么现在更推荐 ECDH 而不是传统 DH?我在项目中验证过,椭圆曲线版本的 DH 可以在同样安全强度下使用更短的密钥,通信量和计算量都小很多。对于移动设备或 IoT 节点来说,性能和带宽都很宝贵。建议直接用 ECDHE(临时 ECDH),它的前向安全性比静态 DH 好——万一长期密钥泄露了,之前会话的密钥不会跟着被破解。

我的调试经验: ECDHE 的曲线选择有讲究。首选 prime256v1(也叫 secp256r1)或 X25519。X25519 在软件实现上速度更快、更不容易被侧信道攻击。我自己最近做的几个项目,基本上都迁移到了 X25519。

公钥基础设施(PKI)

PKI 这一套,说白了就是解决谁信谁的问题。你想确认对方公钥是不是真的,就得靠一个大家信任的第三方来担保。这个第三方就是证书颁发机构(CA)。

我遇到过很多开发者把 PKI 和 HTTPS 画等号,但 PKI 应用远比这个广。你想想,你车上的芯片固件更新、智能门锁的蓝牙配对、企业 VPN 客户端认证,底层都可能是 PKI。

PKI 的典型工作流程是这样:

  • 注册: 客户端生成密钥对,把公钥和身份信息提交给 CA。
  • 签发: CA 对信息做签名,生成数字证书(X.509 格式)。
  • 验证: 对端拿到证书后,用 CA 的公钥验证签名。验证通过说明公钥有效、身份可信。
  • 吊销: 证书泄露或失效时,CA 可以把它标记为吊销,可通过 CRL(证书吊销列表)或 OCSP 查询。
边界系统中的常用做法: 自建 CA 或使用企业 PKI 来做内部设备的证书签发。设备出厂时内置 CA 根证书,然后定期向 CA 申请或更新设备证书。这能让边界网关快速识别哪台设备可信。我在项目里调过不少 CA 的证书链,总结了一些调试经验——确保中间证书的颁发者和最终实体证书的颁发者之间链要完整,不要漏掉中间证书。

但是 PKI 也不是银弹。有些场景下,PKI 的证书管理变得非常复杂。比如说,IoT 设备可能数量巨大且分散,你让它们都定时去 CA 续签证书?网络不稳定怎么办?证书轮换失败怎么办?这些都会造成业务中断。

我踩过的一个大坑: 有一年我参与一个跨国项目,硬件设备分布在中东和东南亚。我们的 PKI 将证书有效期设置为 2 年,结果部分设备因时区设置错误,导致校验证书时间时失效。更可怕的是,我们没来得及建设 OCSP 响应器,只能手动导入 CRL,效率极低。
我的建议: IoT 环境尽量使用短生命周期证书,并配合 OCSP 装订(OCSP Stapling)降低验证延迟。如果设备资源受限,可以考虑使用预共享密钥来简化。

预共享密钥(PSK)

PSK 是什么?简单说,就是通信双方在建立安全通道之前,已经提前共同拥有一个秘密密钥。

这看起来最直接,但很多团队用错了地方。PSK 的典型用法包括:

  • Wi-Fi 网络中的 WPA2/WPA3 预共享密钥。
  • TLS-PSK 模式:直接在 TLS 握手时用 PSK 做身份验证和密钥导出。
  • VPN 连接中的静态密钥认证。

PSK 的优势:实现简单、部署快、无需在线 CA、适合嵌入式设备。但它的劣势也很明显:

  1. 扩展性差。 如果网络里有上百个节点,每两个节点之间都要共享一对密钥,那密钥量就是 O(n²)。管理不过来。
  2. 更换成本高。 密钥一旦泄露,所有共享该密钥的设备都得重新部署。
  3. 缺乏前向安全性。 长期密钥若泄露,历史上所有加密通信都可能被解密。
我建议的混合做法: 在实际项目中,我不推荐纯粹使用 PSK 来构建大规模边界系统。更常见的做法是,用 PSK 作为设备初次注册到管理平台的凭证(相当于“设备的出厂钥匙”),之后安全通道建立后,通过 ECDHE 生成临时会话密钥。这样一来,既利用了 PSK 的简单性,也享受了 ECDHE 的前向安全性。
避坑指南: 我曾经在评估一个嵌入式系统时发现,开发团队将 PSK 硬编码在固件里,且所有设备共享同一个 PSK。一旦有攻击者提取了某台设备的固件,整个系统的通信密钥全被破解了。所以,PSK 绝不能是固定值,最好每个设备一个独立 PSK,并且不能明文存储在非安全区。

三种分发方式的对比

下面这个表格我自己在决策时经常会翻出来看,选型时按照这个思路走基本不会出大错:

特性 Diffie-Hellman (DH/ECDHE) 公钥基础设施 (PKI) 预共享密钥 (PSK)
密钥管理复杂度 中等 较高(需管理CA、CRL、OCSP) 较低(但大规模扩展难)
身份认证支持 需额外签名或证书 原生支持(证书+CA签名) 通过共享秘密隐式认证
前向安全性 立即支持(临时DH) 需要协议配合 不支持(PSK为长期密钥)
防中间人攻击 弱(裸DH无认证) 强(有CA签名链验证) 中等(PSK本身可信)
性能开销 计算量大(DH/ECDHE指数运算) 证书验证、CRL/OCSP处理 极低(对称操作)
离线工作能力 需双方都在线 依赖CA在线 完全离线可用
典型适用场景 TLS 握手、VPN 密钥协商 浏览器、企业设备认证、代码签名 嵌入设备、WPA2网络、少量节点场景
密钥分发与协商核心逻辑 Diffie-Hellman 公钥基础设施(PKI) 预共享密钥(PSK) 共享密钥(离散对数难题) 无身份认证(需签名辅助) CA签发X.509证书 支持吊销/CRL/OCSP 离线共享对称密钥 扩展难、无前向安全 推荐 ECDHE 曲线优选 X25519 或 prime256v1 企业自建CA/短生命周期 OCSP Stapling加速 每个设备独享一个PSK 禁止硬编码/明文存储 混合方案选型建议 PSK注册 → ECDHE会话 → PKI管理长期身份 低安全需求:PSK 内部网络:PKI自建 公开网络:CA验证 高性能需求:ECDHE 低延迟 场景:PSK 结论:选型需权衡安全等级、网络条件、设备算力与管理复杂度 无一种方案最优,按场景组合使用才是王道

关于选型,我的经验是:不要迷恋某一种方案。 很多边界系统设计的失败,正是因为团队想用一个方案解决所有场景。你想想看,企业内部服务器之间通信,肯定是自建 PKI 最稳妥;但如果只是一对蓝牙锁和车主手机配对,你搞个复杂的 PKI 流程用户早疯了,直接 PSK 加临时 DH 就很好。