TLS 固定与 VPN 准入回答的是两个问题
固定限定应用信任哪台服务器;VPN 策略决定谁能进入网络。两者都不覆盖授权,也不覆盖设备丢失。
把一款私有移动应用放到 VPN 之后,讲道理的人会问:它还需要证书固定吗?这个问题听起来像是在两个等价的控制之间做选择,其实问的是两道不同的门。VPN 决定这台设备能否使用这条路径;应用决定它连到的服务器是不是它期待的那一个。分别回答这两个问题,设计反而更简单。
两道门,两个问题
网络准入关心的是客户端:设备是否已登记、凭据是否有效、策略是否允许它走这条路径?应用信任关心的是服务器:连接是否抵达了应用认可其身份的服务?这些答案来自不同系统,因不同原因失败,也由不同团队修复。VPN 握手可以成功,而应用却在与对端背后一张过期的证书对话。即使应用固定得再完美,也可能谁都连不上,因为设备从未进入网络。
两者是叠加的。 去掉其中一个就少一道控制;加上另一个并不能替代它。
固定真正限定的是什么
固定收窄了应用愿意接受的服务器身份集合,通常是点名一个公钥或证书哈希,而不是信任某个存储所担保的每条链。它叠加在常规校验之上,而不是替代常规校验。常规校验回答这条链是否可信;固定回答它是不是这个应用期待的那条链。跳过第一步的实现并没有得到安全,只得到了新鲜感。
被固定的对象因平台而异,所以这个词本身说明不了太多。把一个产品信任存储里的哈希照搬过来,当成移动应用里同样的东西,是常见而安静的失误。
平台上的固定是一种配置,而不是一项策略
Android 通过网络安全性配置来提供固定,其中一个固定集合保存公钥摘要,链中必须至少包含其中一个。该文件按应用配置,需要一次有意的构建变更。iOS 没有等价的清单机制,因此那里的固定存在于应用自己的信任评估代码里。
由于机制不同,需求必须按平台分别书写。只说固定证书却不点名平台的政策是无法落地的。
轮换决定固定能否存活
难的不是第一次发布,而是之后的证书续期。严格的信任策略拒绝一把合法的新密钥,和拒绝攻击者的密钥一样坚决。
有两种机制让轮换可以承受:一把在需要之前就已受信任的备用固定,以及固定集合上的过期日期,让强制失效而不是把应用锁死。两者都是政策决定,而过期尤其是有意降低安全性,不是无害的计时器。点名谁掌控应用构建、TLS 端点与证书续期,并把他们放进同一个变更流程。如果那是三个不同团队,固定迟早会造成一次没人安排过的中断。
设备丢失是第三个问题
吊销 VPN 凭据不一定会结束应用会话,而服务器固定对别人手里的手机毫无作用。设备锁、凭据存储、会话时长与远程吊销是各自独立、各有负责人的决定。把它们折进固定的话题里,等于保证它们一个都不会被设计。
测试四种关系,而不是你能看到的那一种:预期的服务器与操作、一个本应被拒绝的账号、一个本应被拒绝的服务器身份,以及计划中的轮换。能用的 VPN 只演练了第一种。写下每项测试证明了什么,因为下一个人会以为隧道是绿的,就意味着四项全部通过。