前言
笔者是 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
的最大赞助商啊~!