2011-11-29 205 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