2017-08-02 120 views
1

我已經設置CertStore配置了本地存儲的CRL。我只想使用這些本地存儲的CRL進行證書驗證。如果傳入連接的證書與這些CRL中的任何一個都不匹配,則不應嘗試從CDP點獲取CRL,而只是軟失敗。有什麼辦法可以做到這一點?在Java中的CRL檢查

 System.setProperty("com.sun.security.enableCRLDP", "false"); 
     KeyManagerFactory keyManagerFactory = null; 
     KeyStore keyStore = null; 
     keyManagerFactory = KeyManagerFactory.getInstance(keyAlgorithm); 
     keyStore = KeyStore.getInstance(keyStoreType); 
     ksFile = new FileInputStream(keyStoreFile); 
     keyStore.load(ksFile,password); 
     keyManagerFactory.init (keyStore,password); 

     TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX", "SunJSSE"); 
     CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX"); 
     List<CertStore> certStores = new ArrayList<>(); 
     Collection<CRL> crls = new HashSet<>(); 
     crls.add(CertificateFactory.getInstance("X.509").generateCRL(new java.io.FileInputStream("crl path"))); 
     crls.add(CertificateFactory.getInstance("X.509").generateCRL(new java.io.FileInputStream("crl path2"))); 
     certStores.add(CertStore.getInstance("Collection", new CollectionCertStoreParameters(crls))); 
     PKIXRevocationChecker rc = (PKIXRevocationChecker)cpb.getRevocationChecker(); 
     rc.setOptions(EnumSet.of(
      PKIXRevocationChecker.Option.PREFER_CRLS, // prefer CLR over OCSP 
         // handshake should not fail when CRL is not available 
      PKIXRevocationChecker.Option.NO_FALLBACK)); 

     CertPathParameters pkixParams = new PKIXBuilderParameters(keyStore, new X509CertSelector()); 
     // PKIXBuilderParameters pkixParams = new PKIXBuilderParameters(keyStore, new X509CertSelector()); 
     ((PKIXParameters) pkixParams).setRevocationEnabled(true); 
     ((PKIXParameters) pkixParams).setCertStores(certStores); 
     ((PKIXParameters) pkixParams).addCertPathChecker(rc); 

     tmf.init(new CertPathTrustManagerParameters(pkixParams)); 

     SSLContext context = SSLContext.getInstance(protocol); 
        context.init (keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), null); 
+0

您想驗證服務器提供的SSL證書是否創建自己的TrustManager,或者您想在SSLConnection建立後提取SSLL證書並使用您的驗證執行驗證CRL清單? – pedrofb

+0

是在ssl握手期間使用TrustManager。 – supraja

回答

0

審查PKIXRevocationChecker文檔和checkCRLs代碼,我可以看到com.sun.security.enableCRLDP沒有被使用,除非在傳統模式下,和的CRL下載,如果提供者不適合驗證證書

你可以查看/調試DistributionPointFetcher.verifyCRLs中正在應用的標準,瞭解您爲什麼不使用CRL

驗證給定證書的Distri的CRL分配點以確保檢查撤銷狀態是否合適。

static boolean verifyCRL(X509CertImpl certImpl, DistributionPoint point,X509CRL crl, boolean[] reasonsMask, boolean signFlag,PublicKey prevKey, X509Certificate prevCert, String provider,Set<TrustAnchor> trustAnchors, List<CertStore> certStores,Date validity) throws CRLException, IOException { 

替代:檢查吊銷自己

你需要禁用默認撤消檢查使用自己的CRL列表。我想,你可以用默認TrustManager包括被撤銷的服務器證書鏈的信任驗證時檢查

首先拆下((PKIXParameters) pkixParams).setRevocationEnabled(true);,然後添加以下代碼

//tmf.init(...); 

TrustManager[] trustManagers = tmf.getTrustManagers(); 
final X509TrustManager origTrustmanager = (X509TrustManager)trustManagers[0]; 

TrustManager[] wrappedTrustManagers = new TrustManager[]{ 
    new X509TrustManager() { 
     public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
      return origTrustmanager.getAcceptedIssuers(); 
     } 

     public void checkClientTrusted(X509Certificate[] certs, String authType) { 
      origTrustmanager.checkClientTrusted(certs, authType); 
     } 

     public void checkServerTrusted(X509Certificate[] certs, String authType) { 
      //Original trust checking 
      origTrustmanager.checkServerTrusted(certs, authType); 

      //Check revocation with each CRL 
      //from docs: CertificateException - if the certificate chain is not trusted by this TrustManager. 
      for (CRL crl: crls){ 
       if (crl.isRevoked(certs[0]){ 
        throw new CertificateException (e); 
       } 
      } 
     } 
    } 
}; 

免責聲明:餘did't測試,但它應該基於類似的工作examples

+0

因此,如果不創建包裝類,這是不可能的? PKIXRevocation應該做的一切正確嗎?我的代碼是從本地路徑獲取CRL文件,而不是從CDP點下載。但是,當CRL不在本地路徑中時,它將從CDP下載。如何**禁止**從CDP下載CRL? **可能嗎** ? – supraja

+0

我已閱讀文檔和代碼,以瞭解它是如何執行CRL檢查的。似乎有一個先前的驗證,以確保CRLs適合進行驗證。我更新了答案 – pedrofb