Windows 服务器和 Android 客户端出现 CertPathValidatorException

Windows 服务器和 Android 客户端出现 CertPathValidatorException

我在 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 列表更新和不需要的证书恢复时,这样我就知道是时候手动删除它了。

相关内容