2011-11-29 308 views
5

我在我的代码中实施了javax.net.ssl.X509TrustManager,这样我就可以验证我的软件所访问的自签名证书。但是,我仍然需要验证其他一些“标准”网站SSL证书。我正在使用CertPathValidator.validate()来做到这一点,但我只是意识到我正在通过的一个证书链(对于maps.googleapis.com)实际上并不包含完整的链 - 它包含整个链,但包含根CA(Equifax),这在手机上确实存在,但validate()仍然失败,因为(显然)它没有明确地在链中。我在这里错过了什么,以便验证成功?感谢您的任何意见。Android手册X509证书链验证

编辑 - 相关代码(有异常检查删除):

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); 
+0

一些更多的细节:我得到一个'CertPathValidatorException'从调用到'validate()'的错误,** org.bouncycastle.jce.exception.ExtCertPathValidatorException:找不到发行者的CRL“OU = Equifax安全认证中心,O = Equifax,C = US“** – Conrad

回答

2

实现您自己的TrustManager通常是一个坏主意。更好的方法是将证书添加到密钥库中,并将其添加为信任库。有关如何操作的示例,请参阅this

您可能需要将缺省信任库添加到验证程序中。另外,Android不会在默认情况下进行吊销(CRL)检查,所以如果启用了它,则需要手动获取相关的CRL。发布您的代码。

+0

感谢您的链接 - 我会检查出来。 – Conrad

+0

这看起来是正确的答案,但我使用调用DefaultHttpClient的第三方库,我不想重新编译它们,所以我只会让我对maps.googleapis.com的调用不安全。这点。感谢指针。 – Conrad

+0

@尼科莱,“实施自己的TrustManager通常是一个糟糕的主意。” 我同意。但是,我们需要使用CRL验证证书。 Android不是。我们如何解决它? – 2017-05-25 13:02:27