为什么 Java / Apache HttpClient 使用与我的浏览器不同且已过期的 X509 根证书?

问题描述

对于 Stack Exchange project,我正在使用使用 Apache HttpClient 的 Java 程序从互联网上下载各种链接。它会检查过期的 SSL 证书,这可能是图像不再可见的原因之一。

我注意到有时,Java 程序认为 SSL 证书已过期,而我的浏览器认为它没有过期。一个示例是以下 URL:https://www.dewharvest.com/uploads/3/4/5/4/34546214/oak-from-seed_orig.jpg

我的浏览器(macOS 上的 Firefox)认为它有效:

但是当我运行下面的剥离 Java 程序时,这就是我得到的:

reject

顺序不同(末端实体;根;中间),您可以看到末端实体的指纹和序列号,中间一个与我的浏览器匹配。根证书不一样,主要问题是这个证书有效期到去年5月份。这里发生了什么事?我检查了我的 Java 密钥库(使用 Name: CN=www.dewharvest.com Not after: Tue Feb 09 00:59:59 CET 2021 Not before: Fri Feb 07 01:00:00 CET 2020 Serial #: 6f698f95c0f23b77fb181bf76141b080 Thumbprint: 580d0025564d9603ede46f6aba03dfc5045d207a Name: CN=USERTrust RSA Certification Authority,O=The USERTRUST Network,L=Jersey City,ST=New Jersey,C=US Not after: Sat May 30 12:48:38 CEST 2020 Not before: Tue May 30 12:48:38 CEST 2000 Serial #: 13ea28705bf4eced0c36630980614336 Thumbprint: eab040689a0d805b5d6fd654fc168cff00b78be3 Name: CN=Sectigo RSA Domain Validation Secure Server CA,O=Sectigo Limited,L=Salford,ST=Greater Manchester,C=GB Not after: Wed Jan 01 00:59:59 CET 2031 Not before: Fri Nov 02 01:00:00 CET 2018 Serial #: 7d5b5126b476ba11db74160bbc530da7 Thumbprint: 33e4e80807204c2b6182a3a14b591acd25b5f0db ),它包含与我的浏览器相同的根证书,但没有上面过期的根证书:

keytool -list

Java 程序来了;我正在使用 version 4.5.11 of Apache HttpClient,但更新到 4.5.13 没有帮助。

usertrustrsaca [jdk],Aug 25,2016,trustedCertEntry,Certificate fingerprint (SHA1): 2B:8F:1B:57:33:0D:BB:A2:D0:7A:6C:51:F7:0E:E9:0D:DA:B9:AD:8E

解决方法

Certigo 存在特定问题,请参阅: What happens if I have expired additional certificate in the chain with alternate trust path?

如果我理解正确的话,该网站的所有者应该已经从他们的证书链中删除了旧的根证书,因为新的根证书默认安装在浏览器和 Java 的信任库中,如您所见。

SSLMate 有一个不错的在线测试器:https://whatsmychaincert.com/?www.dewharvest.com

浏览器和 Java 的 TrustManager 的区别在于,在 Java 中,如果证书链中的证书已过期,则不再检查替代证书(在本地信任库中)。

我记得在 Java 6 或 7 中,有一个不同的问题,即只在最终证书上检查到期日期,而不是在中间证书上检查,但我不记得他们是什么时候修复的。