我在Windows Server 2008 R2计算机上从Comodo安装了一个新的PositiveSSL证书。 我从以下客户端成功连接
到以下服务器
但是,当我使用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操作系统根CA存储,或者至less具有不同的信任validation逻辑。
我安装的证书直接来自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文件导入到计算机帐户的证书MMCpipe理单元中。 我在“SSL&TLS> MDaemon”下的“MDaemon安全设置”对话框中select了新的证书,然后点击“重新启动服务器”。 使用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没有path?
答案来自Comodo知识库文章: Android上不受信任的证书错误 。
错误的原因是默认Windows证书存储中的现有Comodo证书。 其中一个中间证书即COMODO RSA Certification Authority默认存在于受信任的根证书颁发机构文件夹中,作为自颁发的CA证书。 我没有安装它,Windows有一个股票安装。 我不确定为什么它在那里,因为真正的COMODO RSA证书颁发机构由AddTrust发布,而不是它本身,并且指纹不匹配。 此外,这个虚假自发的Comodo Root CA在Android 4.4的根存储中不存在,即使除了检查指纹外,还有其他三个与CN相似的Comodo CA。 也许在Comodo和AddTrust之间有一些与CA重组有关的历史原因。
从KB文章的解决scheme已经修复了K-9的错误:从Windows受信任的根证书颁发机构中删除自我颁发的COMODO RSA证书颁发机构(我实际上剪切并粘贴到不同的文件夹,以防我需要恢复更改,而不是永久删除它)。
这个伪造的证书使得MDaemon认为更高级别的中间Comodo证书实际上是一个根证书,并没有通过SSL握手发送给K-9。 这在s_client输出中显示出来,但对我来说并不明显。 在修复之前,MDaemon只发送链中的最低两个证书,Android没有从第三个证书(Comodo域validation)到AddTrust的信任path,因为响应中缺less第二个证书。 修复之后,MDaemon发送了链中最低的三个证书,Android能够成功find从Comodo Certification CA到AddTrust的path。
一个未解决的项目是Windows自动根CA更新。 Comodo警告说,这些更新会将不需要的证书还原到受信任的根CA存储,并build议您禁用所有根CA更新。 我认为这不是最好的解决scheme,因为我希望根CA列表跟上这个例外。 我正在考虑试图find或写一个程序,可以从计算机证书存储删除给定的证书,并定期运行。 也许有一个我可以写的PowerShell或基于certmgr.exe的脚本。 至less,也许我可以添加一些自动化监控,当根CA列表更新,不需要的证书恢复,所以我知道是时候手动删除它。