前言
笔者是 Let's Encrypt 的重度用户, 在今年初注意到 Let's Encrypt 使用 DST Root CA X3 为根证书的证书链的中级证书 ISRG Root X1 由于根证书 DST Root CA X3 即将在 2021/09/30 22:01:15 到期, 届时该条证书链将失效, 会使得 Let's Encrypt 将证书链全面迁移到自有的 ISRG Root X1 根证书之中, 如果这个方案实施, 会使笔者一些设备无法访问使用 Let's Encrypt 证书的网站.
但最近笔者在浏览 Let's Encrypt 文档时注意到, Let's Encrypt 已经找到一个 新方案 使一些使用 Android 老系统的设备可以持续正常使用到 2024/10/01 02:14:03, 这个操作很骚啊, 于是根据公开的相关文档做了一个与原理分析.
问题来源
Let's Encrypt 作为 免费、自动化和开放的证书颁发机构 在成立之初直接使用了 Digital Signature Trust Co. 的根CA证书 DST Root CA X3 所颁发的中级CA证书 Let's Encrypt R3 向用户颁发服务器证书.
后来发展到一定规模 Let's Encrypt 也推出了自有的CA根证书 ISRG Root X1, 但由于一些老设备由于使用的操作系统不再更新, ISRG Root X1 在这些老设备中并没有得到信任(即这些操作系统中信任的CA证书不包含 ISRG Root X1).
经过时间的推移, 问题就出现了, 由于 Digital Signature Trust Co. 的根CA证书 DST Root CA X3 即将在 2021/09/30 22:01:15 到期, 需要切换到 ISRG Root X1 根CA证书, 但又因为一些老设备并没有信任 ISRG Root X1, 如果强行切到 ISRG Root X1, 那这些不信任 ISRG Root X1 的老设备默认将无法访问使用 Let's Encrypt 证书的网站(例如使用 Android 7.1.1 之前系统的设备, 使用 iOS 9 及之前系统的设备, 使用 macOS 10.12.1 之前系统的设备等), 这代价无疑是巨大的.
相比之下, DST Root CA X3 的兼容性就要好很多.
所幸经过 Let's Encrypt 一番努力, 找到一条尽可能减少损失的新方案.
Android 的特别之处
首先 Let's Encrypt 会有这个 “新方案” 的最根本原因就是因为发现了 Android 平台在处理证书的一个特别之处.
在 Android 平台, 操作系统故意不强制执行用作信任锚的证书的过期日期.
简单来说就是 Android 只会校验网站证书和中级证书 ISRG Root X1 的有效期, 而会忽略 DST Root CA X3 的有效期.
但这个规则只适用于 Android, 别的操作系统又该怎么办?
如何兼容其他系统?
上面提到, Android 会忽略 DST Root CA X3 已经过期的事实, 但别的操作系统可不会这样处理, 正常的处理都是检验整个证书链每一个证书的有效期, 某一个证书失效均会导致整个证书链失效.
如果能让 DST Root CA X3 和 ISRG Root X1 同时生效, 问题就能解决了.
交叉签名
这就引入了最核心的技术 cross-signed, 即 交叉签名, 通过这个技术, 就能实现让 DST Root CA X3 和 ISRG Root X1 同时生效.
启用了交叉签名之后, 证书链大概是这样的: DST Root CA X3 => ISRG Root X1 => Let’s Encrypt R3; 在普通系统中, 由于 ISRG Root X1 被信任, 检查证书链时不会检查已过期的 DST Root CA X3, 证书链校验通过; 在旧版本的 Android 系统当中, 此时 ISRG Root X1 不被信任, 会验证 DST Root CA X3, 虽然此时 DST Root CA X3 已经过期, 但由于 Android 系统的特殊性, 过期的 DST Root CA X3 任然被认为是有效的, 证书链也检验通过.
为什么
DST Root CA X3交叉签名后的证书链任然能够被只信任了ISRG Root X1根CA的操作系统信任呢?
在X.509体系中, 证书由公钥,证书信息和CA签名组成, 其中公钥和私钥是一对一的关系, 由于交叉签名使用的私钥是同一个, 所以交叉签名的ISRG Root X1二级证书和操作系统中的ISRG Root X1根CA证书公钥相同, 证书信息也相同, 只有其中的CA签名一个来自DST Root CA X3, 另一个来自ISRG Root X1本身, 而证书校验是比较的用证书公钥解密后的证书信息, 所以即便是 CA签名 不同, 这两张证书仍旧被视为同一个证书.
总结
从分析来看, Let's Encrypt 这套方案不仅启用了新的根CA证书 ISRG Root X1, 也支持了使用 Android 旧版本系统的设备, 可谓一举双得, 就不知道2024年的时候又该怎么办, 只能希望这些设备当那个时候都没人用了吧, 吾辈加油!
对于 macOS 10, iOS 9, Ubuntu 14 这些系统, 只能祈祷 Let's Encrypt 能找到一个更持久的大厂CA来做个交叉签名, 但就现在这个时间来看, 这个操作已经来不及了, 并且也不太现实, 因为 Digital Signature Trust Co. 是 Let's Encrypt 的最大赞助商啊~!