我已经设置了用本地存储的CRL配置的CertStore。我只想使用这些本地存储的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);发布于 2017-08-02 12:23:23
回顾PKIXRevocationChecker文档和校验checkCRLs代码,我可以看到,除了在遗留模式下,com.sun.security.enableCRLDP没有被使用,如果提供的com.sun.security.enableCRLDP不适合验证证书,则会下载CRLs。
您可以检查/调试在DistributionPointFetcher.verifyCRLs中应用的条件,以了解不使用CRLs的原因。
验证给定证书的分发点的CRL,以确保它适合检查吊销状态。 静态布尔verifyCRL(X509CertImpl certImpl,DistributionPoint point,X509CRL crl,boolean[] reasonsMask,布尔signFlag,PublicKey prevKey,X509Certificate prevCert,String provider,Set trustAnchors,List certStores,日期有效性)抛出CRLException,IOException {
Alternative:自己检查吊销
您需要禁用默认吊销检查才能使用您自己的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);
}
}
}
}
};免责声明:我没有测试它,但是它应该基于类似的示例工作
https://stackoverflow.com/questions/45460015
复制相似问题