【问题标题】:CRL check in JavaJava 中的 CRL 检查
【发布时间】:2017-08-02 11:45:56
【问题描述】:

我已将 CertStore 设置为配置有本地存储的 CRL。我只想使用这些本地存储的 CRL 执行证书验证。如果传入连接的证书与这些 CRL 中的任何一个都不匹配,则不应尝试从 CDP 点获取 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);

【问题讨论】:

  • 您要验证由创建您自己的TrustManager 的服务器提供的 SSL 证书,还是要在 SSLConnection 建立后提取 SSLL 证书并使用您的 CRL 列表执行验证?
  • 是的,在 ssl 握手期间使用 TrustManager..

标签: java ssl x509certificate certificate-revocation


【解决方案1】:

查看PKIXRevocationChecker 文档和checkCRLs 代码,我可以看到com.sun.security.enableCRLDP 除了在旧模式下没有被使用,并且如果提供的CRL 不适合验证证书,则会下载CRL

您可以查看/调试在 DistributionPointFetcher.verifyCRLs 中应用的标准,以了解您的 CRL 未被使用的原因

验证给定证书的分发点的 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);
               }
           }
       }
   }
};

免责声明:我没有测试它,但它应该基于类似的examples 工作

【讨论】:

  • 那么不创建包装类就不可能吗? PKIXRevocation 应该做这一切对吗?我的代码是从本地路径获取 CRL 文件,而不是从 CDP 点下载。但是当本地路径中不存在 CRL 时,它是从 CDP 下载的。如何禁止从 CDP 下载 CRL? 有可能吗?
  • 我查看了文档和代码以了解它是如何执行 CRL 检查的。似乎有一个先前的验证来确保 CRL 适合进行验证。我更新了答案
猜你喜欢
  • 2015-08-09
  • 1970-01-01
  • 2012-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-22
  • 2018-12-30
相关资源
最近更新 更多