![Windows 服务器和 Android 客户端出现 CertPathValidatorException](https://linux22.com/image/704607/Windows%20%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%92%8C%20Android%20%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%87%BA%E7%8E%B0%20CertPathValidatorException.png)
我在 Windows Server 2008 R2 计算机上安装了 Comodo 的新 PositiveSSL 证书。我成功从以下客户端连接
- 适用于 Windows 的 Chrome
- Android 版 Chrome
- Windows 版 Firefox
- IE浏览器
- 适用于 Windows 的 Vivaldi
- Windows 版 Opera(HTTPS 和 IMAP)
- Windows 的远程桌面连接
到以下服务器
- 带有 mod_ssl 的 Apache
- 远程桌面服务
- 守护进程
但是,当我使用 K-9 Mail for Android 连接到 MDaemon 时,出现错误
java.security.cert.CertPathValidatorException: Trust Anchor for certificate path not found
我认为 Chrome 和 K-9 在同一部手机上的表现不同,因为 Android 版 Chrome 附带自己的 Root CA 存储,并且不依赖于 Android OS Root CA 存储,或者至少具有不同的信任验证逻辑。
我安装的证书直接来自 Comodo 通过电子邮件发送给我的 ZIP 文件:
AddTrustExternalCARoot.crt (this is the root CA)
COMODORSAAddTrustCA.crt (this is a higher-level intermediate CA)
COMODORSADomainValidationSecureServerCA.crt (this is a lower-level intermediate CA)
www_myserver_com.crt (this is my server's cert)
当我将这些证书安装到 Windows 证书存储中以供 RDP 和 MDaemon 使用时,我使用以下命令将这些证书转换为 PKCS12 文件
cat "./www_myserver_com.crt" "./COMODORSADomainValidationSecureServerCA.crt" "./COMODORSAAddTrustCA.crt" "AddTrustExternalCARoot.crt" > "./fullchain.crt"
openssl pkcs12 -in "./fullchain.crt" -inkey "./www_myserver_com.key" -out "./fullchain.pfx" -export
然后使用自动存储目标将 PFX 文件导入计算机帐户的证书 MMC 管理单元。我在 MDaemon 的安全设置对话框中的 SSL 和 TLS > MDaemon 下选择了新证书,然后点击重新启动服务器。使用 OpenSSL,我可以看到正确的证书与中间证书一起提供。
C:\>openssl s_client -connect myserver.com:993
CONNECTED(00000003)
depth=2 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN
= COMODO RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN
= COMODO RSA Domain Validation Secure Server CA
verify return:1
depth=0 OU = Domain Control Validated, OU = PositiveSSL, CN = www.myserver.com
verify return:1
---
Certificate chain
0 s:/OU=Domain Control Validated/OU=PositiveSSL/CN=www.myserver.com
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Dom
ain Validation Secure Server CA
1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Dom
ain Validation Secure Server CA
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Cer
tification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MII..8hg==
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/OU=PositiveSSL/CN=www.myserver.com
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA D
omain Validation Secure Server CA
---
No client certificate CA names sent
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3401 bytes and written 450 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1
Cipher : ECDHE-RSA-AES256-SHA
Session-ID: F04A0000068E4DC91357783440DA44EEB39DA3C813C3C646EBCE29DDD3E8C139
Session-ID-ctx:
Master-Key: FF3D72A03F1F93686AC6EAB38198036C7AF1780250ED3F510A83CE6DC166778F
A726DBC2AA4ED6C5277A0969D175E419
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1495135778
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
我查看了 Android 中的证书链以及根 CA 是否在 Android 的 CA 存储中。
这是预期的完整证书链。以下名称是通用名称 (CN)。
AddTrust External CA Root
└─COMODO RSA Certification Authority
└─COMODO RSA Domain Validation Secure Server CA
└─www.myserver.com
我看到 AddTrust External CA Root 确实存在于 Android 证书存储区中,并且具有正确的指纹。
为什么 K-9 Mail 会抛出错误,指出从我的服务器的 TLS 证书到受信任的根 CA 没有路径?
答案1
答案来自 Comodo 知识库文章:Android 上不受信任的证书错误。
错误的原因在于默认 Windows 证书存储区中现有的 Comodo 证书。中间证书之一,COMODO RSA Certification Authority
作为自颁发的 CA 证书默认存在于受信任的根证书颁发机构文件夹中。我没有将它安装在那里,Windows 已将其安装在标准安装中。我不确定它为什么在那里,因为真正的 COMODO RSA 证书颁发机构是由 AddTrust 颁发的,而不是它自己,而且指纹不匹配。此外,这个伪造的自颁发的 Comodo Root CA 不存在于 Android 4.4 的根存储区中,即使还有其他三个 Comodo CA 的 CN 非常相似,除非您检查指纹,否则会造成混淆。也许存在与 Comodo 和 AddTrust 之间的 CA 重组相关的一些历史原因。
KB 文章中的解决方案已修复 K-9 中的错误:从 Windows 受信任的根证书颁发机构中删除自行颁发的 COMODO RSA 证书颁发机构(我实际上将其剪切并粘贴到另一个文件夹中,以防我需要恢复更改,而不是永久删除它)。
这个伪造的证书导致 MDaemon 认为更高级别的中间 Comodo 证书实际上是根证书,因此它没有在 SSL 握手中将其发送给 K-9。s_client 输出中指出了这一点,但对我来说还不够明显。修复之前,MDaemon 只发送链中最后两个证书,而 Android 没有从第三个证书(Comodo 域验证)到 AddTrust 的信任路径,因为响应中缺少第二个证书。修复后,MDaemon 发送了链中最后三个证书,Android 能够成功找到从 Comodo 认证 CA 到 AddTrust 的路径。
一个未解决的问题就是 Windows 自动根 CA 更新。Comodo 警告说,这些更新会将不需要的证书恢复到受信任的根 CA 存储,并建议您禁用所有根 CA 更新。我认为这不是最好的解决方案,因为我希望根 CA 列表保持最新状态,但只有这一个例外。我正在考虑尝试查找或编写一个程序,该程序可以从计算机证书存储中删除给定的证书并定期运行。也许我可以编写一个基于 PowerShell 或 certmgr.exe 的脚本。至少,也许我可以添加一些自动监控,当根 CA 列表更新和不需要的证书恢复时,这样我就知道是时候手动删除它了。