2012-04-06 436 views
12

我試圖在幾個步驟中處理X509證書,並遇到一些問題。我是JCE的新手,所以我沒有完全掌握所有內容。Java X509證書解析和驗證

我們希望能夠根據不同的編碼(PEM,DER和PCKS7)解析幾個不同的X509證書。我已經使用FireFox(證書包括鏈),以PEM和PCKS7格式從https://belgium.be導出了相同的證書。我已經離開那些不需要的問題

public List<X509Certificate> parse(FileInputStream fis) { 
    /* 
    * Generate a X509 Certificate initialized with the data read from the inputstream. 
    * NOTE: Generation fails when using BufferedInputStream on PKCS7 certificates. 
    */ 
    List<X509Certificate> certificates = null; 
     log.debug("Parsing new certificate."); 
     certificates = (List<X509Certificate>) cf.generateCertificates(fis); 
    return certificates; 
    } 

此代碼幾行了工作正常aslong我與一個FileInputStream而不是爲PCKS7一個的BufferedInputStream,這已經是我覺得挺奇怪的工作嗎?但我可以忍受它。

下一步是驗證這些證書鏈。 1)檢查所有證書是否有有效日期(簡單) 2)使用OCSP驗證證書鏈(如果證書中沒有找到OCSP URL,則回退到CRL)。這是我不完全確定如何處理這個問題的地方。

我正在使用Sun JCE,但它似乎沒有那麼多文檔可用(在示例中)?

我首先做了一個簡單的實現,只檢查鏈而不經過OCSP/CRL檢查。

private Boolean validateChain(List<X509Certificate> certificates) { 
    PKIXParameters params; 
    CertPath certPath; 
    CertPathValidator certPathValidator; 
    Boolean valid = Boolean.FALSE; 

    params = new PKIXParameters(keyStore); 
    params.setRevocationEnabled(false); 

    certPath = cf.generateCertPath(certificates); 
    certPathValidator = CertPathValidator.getInstance("PKIX"); 

    PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) 
    certPathValidator.validate(certPath, params); 

     if(null != result) { 
     valid = Boolean.TRUE; 
     } 
    return valid; 
} 

這是對我的PEM證書工作正常,但不是爲PCKS7證書(相同的認證文件,只出口在其他格式)。 java.security.cert.CertPathValidatorException:路徑不鏈接任何信任錨。

我能看到的唯一區別是CertPath的形成順序是不一樣的?我無法弄清楚發生了什麼事情錯了,所以我離開了這個現在並保持在與PEM證書去,但讓我們稱之爲這個問題1)

我想要實現之後是OCSP檢查。 顯然,如果我啓用OCSP使用:Security.setProperty(「ocsp.enable」,「true」);並設置params.setRevocationEnabled(true); 它應該能夠自己找到OCSP URL,但似乎並不是這樣。標準實施應該做什麼(問題2)? java.security.cert.CertPathValidatorException:必須指定的OCSP響應

走出過去這個位置,我找到了一種方法來檢索使用AuthorityInfoAccessExtension和這種證書的OCSP URL。

但在ocsp.url屬性手動設置OCSP URL後,我發現了一個java.security.cert.CertPathValidatorException:OCSP響應錯誤:未經授權

好像我錯過了很多必要的步驟,而很多在線參考文獻說,設置ocsp.enable屬性應該是你需要做的一切嗎?

也許你們中的任何一個人都不能指導我完成整個過程?告訴我我完全錯誤的地方:)

如果沒有找到OCSP,下一步將執行CRL檢查,如果任何人都可以指出任何示例或向我展示一些文檔,這也將非常感謝!

謝謝!

編輯: 因爲它不是拿起自身的屬性,我一直在試圖利用對自己設置的所有屬性如下:

// Activate OCSP 
     Security.setProperty("ocsp.enable", "true"); 
     // Activate CRLDP -- no idea what this is 
     Security.setProperty("com.sun.security.enableCRLDP", "true"); 

     X509Certificate target = (X509Certificate) certPath.getCertificates().get(0); 
     Security.setProperty("ocsp.responderURL","http://ocsp.pki.belgium.be/"); 
     Security.setProperty("ocsp.responderCertIssuerName", target.getIssuerX500Principal().getName()); 
     Security.setProperty("ocsp.responderCertSubjectName", target.getSubjectX500Principal().getName()); 
     Security.setProperty("ocsp.responderCertSerialNumber", target.getSerialNumber().toString(16)); 

這給出了一個例外: 的Java。 security.cert.CertPathValidatorException:找不到響應者的證書(使用OCSP安全屬性進行設置)。

+0

OSCPChecker似乎在getOCSPServerURI方法中執行此操作:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/security/provider/certpath/OCSPChecker .java#OCSPChecker.getOCSPServerURI%28sun.security.x509.X509CertImpl%2Cjava.lang.String%29 – 2014-03-17 18:46:28

+0

在你的例子中'cf'是什麼? – spy 2017-08-29 14:33:20

+0

這已經很久了,但我會說https://docs.oracle.com/javase/7/docs/api/java/security/cert/CertificateFactory.html – 2017-08-29 14:35:23

回答

15

以供將來參考我的答案後,以我自己的問題(部分ATLEAST)

OCSP和CRL檢查標準Java實現已經實現,沒有必要爲自定義代碼或其他供應商(公元前,..)。它們默認是禁用的。

爲了實現這一目標,你必須ATLEAST設置兩個參數:

(PKIXParameters or PKIXParameterBuilder) params.setRevocationEnabled(true); 
Security.setProperty("ocsp.enable", "true"); 

這將激活OCSP檢查,當你試圖驗證證書路徑(PKIXCertPathValidatorResult.validate())。

當你想添加的回退檢查CRL如果沒有OCSP可用,添加aditional的屬性:

System.setProperty("com.sun.security.enableCRLDP", "true"); 

我的很多問題正在發生,由於這樣的事實,我必須支持不同的證書格式(PKCS7,PEM)。我的執行工作正常PEM,但由於PKCS7不保存證書的順序鏈是有點困難(http://bugs.sun.com/view_bug.do?bug_id=6238093

X509CertSelector targetConstraints = new X509CertSelector(); 

targetConstraints.setCertificate(certificates.get(0)); 
// Here's the issue for PKCS7 certificates since they are not ordered, 
// but I havent figured out how I can see what the target certificate 
// (lowest level) is in the incoming certificates.. 

PKIXBuilderParameters params = new PKIXBuilderParameters(anchors, targetConstraints); 

希望這將成爲其他人有用的話爲好,也許有人能闡明瞭如何在一個無序的PKCS7列表中找到目標證書?