Android手动X509证书链验证

5
我已经在我的代码中实现了javax.net.ssl.X509TrustManager,以验证我使用的自签名证书。但是,我仍然需要验证一些其他“标准”的网站SSL证书。我正在使用CertPathValidator.validate()来完成这个任务,但我刚意识到我被传递的一个证书链(maps.googleapis.com)并没有包含完整的链 - 它包含整个链,但缺少根CA(Equifax),尽管该CA存在于手机中,但validate()仍然失败,因为(显然)它没有明确地出现在链中。请问我漏掉了什么,以便进行验证成功?谢谢任何回答。
编辑-相关代码(已删除异常检查):
CertificateFactory cf = CertificateFactory.getInstance("X.509");
// chain is of type X509Certificate[]
CertPath cp = cf.generateCertPath(Arrays.asList(chain));

CertPathValidator cpv = CertPathValidator.getInstance(CertPathValidator.getDefaultType());
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());

FileInputStream is = new FileInputStream("/system/etc/security/cacerts.bks");
ks.load(is, null);

PKIXParameters params = new PKIXParameters(ks);
CertPathValidatorResult cpvr = cpv.validate(cp, params);

更多细节:在调用validate()时,我收到了一个CertPathValidatorException错误,错误信息为**org.bouncycastle.jce.exception.ExtCertPathValidatorException: No CRLs found for issuer "OU=Equifax Secure Certificate Authority, O=Equifax, C=US"**。 - Conrad
1个回答

2
实现自己的TrustManager通常是不好的做法。更好的方法是将您的证书添加到密钥库中,并将其作为信任库添加。参见此处以了解如何执行此操作的示例。
您可能需要向验证器添加默认信任库。此外,默认情况下,Android不执行撤销(CRL)检查,因此如果启用了它,则需要手动获取相关的CRL。请发布您的代码。

谢谢提供链接 - 我会去查看的。 - Conrad
这看起来是正确的答案,但我正在使用调用DefaultHttpClient的第三方库,我不想重新编译它们,所以我将让我的maps.googleapis.com调用在此时不安全。感谢指引。 - Conrad
@Nikolay,“实现自己的TrustManager通常是个坏主意。” 我同意。但是,我们需要使用CRL验证证书。Android没有提供此功能。我们该如何解决这个问题? - user7118603

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接