最近在更新公司的 SSL 憑證時,發現部分服務的 Java keystore 不認識該 SSL 憑證的 Root CA 而無法進行 HTTPS 交握。
解法寫在前面
Sectigo 的 AddTrust 中繼憑證於 2020/06/01 過期,很多網站拿到 2018 前簽發的憑證如果 CA file 沒有更新都會遇到 certificate has expired
的問題,這個問題通常在 Server Side 會遇到,因為原本 CA list 仍然將 AddTrust 放在信任名單內
*** 6/1 晚上 ca-certificates 已經更新 CA List 清單「USN-4377-1: ca-certificates update」
直接執行 update-ca-certificates
就可以,查看 /etc/ca-certificates.conf
設定檔可以看到 mozillaAddTrust_*
被註解
!mozilla/AddTrust_External_Root.crt
!mozilla/AddTrust_Low-Value_Services_Root.crt
!mozilla/AddTrust_Public_Services_Root.crt
!mozilla/AddTrust_Qualified_Certificates_Root.crt
*** 手動處理
要解決這個問題可以直接將 /etc/ca-certificates.conf 裡面的 mozilla/AddTrust_External_Root.crt 拿掉後更新就好
- 將 mozilla/AddTrust_External_Root.crt 註解或刪除
# /etc/ca-certificates.conf
!mozilla/AddTrust_External_Root.crt
- 更新 CA file 清單
$ update-ca-certificates
Updating certificates in /etc/ssl/certs...
0 added, 1 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
確認有 1 個 certificates 被移除 (即是 mozilla/AddTrust_External_Root.crt)
- cURL 測試原本 certificate has expired 的網站
$ curl https://shazi.info
事件查詢過程
記得幾年前開始公司就都是以 Gandi 換發的 SSL 憑證為主,當時就已經針對 Gandi 的 Root CA (AddTrust) 匯入過 Java keystore 一次了,理論上不需要再匯入 Root CA 才對,怎麼又會遇到 Root CA 信任問題 !?
仔細比較一下前後換發的 SSL 憑證 Certificate chain
- 2018 年簽發的 Gandi 憑證
0 s:/OU=Domain Control Validated/OU=Gandi Standard Wildcard SSL/CN=*.com
i:/C=FR/ST=Paris/L=Paris/O=Gandi/CN=Gandi Standard SSL CA 2
1 s:/C=FR/ST=Paris/L=Paris/O=Gandi/CN=Gandi Standard SSL CA 2
i:/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority
2 s:/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
- 2019 年 2 月簽發的 Gandi 憑證
0 s:/CN=*.com
i:/C=FR/ST=Paris/L=Paris/O=Gandi/CN=Gandi Standard SSL CA 2
1 s:/C=FR/ST=Paris/L=Paris/O=Gandi/CN=Gandi Standard SSL CA 2
i:/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority
查看後發現兩張憑證簽發的 Root CA 竟然不同,但都是由 Gandi 簽發,而 Gandi 文件內也有提到上層 Root CA 都是由 Sectigo (Comodo CA) 簽發,理論上不應該 Root CA 不同才對。
Installation of the intermediate cert is MANDATORY for ALL TYPES of SSL certificates, as Gandi is not a CA, Sectigo is. We need to install the intermediate certificate to complete the certification chain between the issuer (Gandi) and the root CA (Comodo).
後來在 Sectigo 的「Sectigo Chain Hierarchy and Intermediate Roots」找到原因,原來是因為原本的 Root CA AddTrust 到 2020 年 5 月就過期了,並且 AddTrust 當時是以 sha1WithRSAEncryption 簽發,所以乾脆就採用第二層的 USERTrust 作為 Root CA 簽發。
自從 2019 年 1 月後透過 Sectigo 簽發的 SSL 憑證都是以 USERTrust 為 Root CA,也因為更改了 Root CA 在沒有 Internet 的 Java 就無法自動更新 Root CA,必須重新匯入到 keystore。
在一些比較新的系統上都能看到已經把 USERTrust 加到信任的 Root CA 列表,例如 macOS Sierra,但是比較舊的系統又沒有 Internet 可以訪問的話,就會遇到 Root CA 不信任而無法進行 SSL 交握
這點其實蠻雷的,但看起來每一家 Root CA 都會遇到 renew 的問題,新的 USERTrust 簽發到 2038 年 … 下一次 18 年後應該也要退休了 XDDD
Reference