Java中的CRL检查
我已使用本地存储的CRL设置CertStore。我只想使用这些本地存储的CRL执行证书验证。如果传入连接的证书与这些CRL中的任何一个都不匹配,则它不应该尝试从CDP点获取CRL,而只是softfail。有没有办法做到这一点Java中的CRL检查,java,ssl,x509certificate,certificate-revocation,Java,Ssl,X509certificate,Certificate Revocation,我已使用本地存储的CRL设置CertStore。我只想使用这些本地存储的CRL执行证书验证。如果传入连接的证书与这些CRL中的任何一个都不匹配,则它不应该尝试从CDP点获取CRL,而只是softfail。有没有办法做到这一点 System.setProperty("com.sun.security.enableCRLDP", "false"); KeyManagerFactory keyManagerFactory = null; KeyStore
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);
System.setProperty(“com.sun.security.enableCRLDP”、“false”);
KeyManagerFactory KeyManagerFactory=null;
密钥库KeyStore=null;
keyManagerFactory=keyManagerFactory.getInstance(keyAlgorithm);
keyStore=keyStore.getInstance(keyStoreType);
ksFile=新文件输入流(keyStoreFile);
load(ksFile,密码);
keyManagerFactory.init(密钥库、密码);
TrustManagerFactory tmf=TrustManagerFactory.getInstance(“PKIX”、“SunJSSE”);
CertPathBuilder cpb=CertPathBuilder.getInstance(“PKIX”);
List certStores=new ArrayList();
集合crls=新的HashSet();
add(CertificateFactory.getInstance(“X.509”).generateCRL(新的java.io.FileInputStream(“crl路径”));
添加(CertificateFactory.getInstance(“X.509”).generateCRL(新java.io.FileInputStream(“crl路径2”));
添加(CertStore.getInstance(“Collection”,新的CollectionCertStoreParameters(crls));
PKIXRevocationChecker rc=(PKIXRevocationChecker)cpb.getRevocationChecker();
rc.setOptions(EnumSet.of(
PKIXRevocationChecker.Option.preference_CRLS,//首选CLR而非OCSP
//当CRL不可用时,握手不应失败
PKIXRevocationChecker.Option.NO_FALLBACK));
CertPathParameters pkixParams=新的PKIXBuilderParameters(密钥库,新的X509CertSelector());
//PKIXBuilderParameters pkixParams=新的PKIXBuilderParameters(密钥库,新的X509CertSelector());
((PKIXParameters)pkixParams).setRevocationEnabled(true);
(pkixparames)pkixParams.setCertStores(certStores);
((pkixparames)pkixParams.addCertPathChecker(rc);
init(新的CertPathTrustManagerParameters(pkixParams));
SSLContext context=SSLContext.getInstance(协议);
context.init(keyManagerFactory.getKeyManagers(),tmf.getTrustManagers(),null);
查看文档和代码,我可以看到com.sun.security.enableCRLDP
除了在传统模式下使用外,没有被使用,如果提供的CRL不适合验证证书,则下载CRL
您可以查看/调试中应用的条件,以了解不使用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 {
免责声明:我没有测试它,但它应该基于类似的工作。是否要验证创建您自己的
TrustManager
的服务器提供的SSL证书,或者,是否要在建立ssl连接后提取SSLL证书,并使用CRL列表执行验证?是的,在ssl握手期间使用TrustManager。因此,如果不创建包装类,是否不可能?你应该把这些都做好吗?我的代码从本地路径获取CRL文件,而不是从CDP点下载。。但当CRL不在本地路径中时,它是从CDP下载的。如何禁止从CDP下载CRL?可能吗?我已经检查了文档和代码,以了解如何执行CRL检查。似乎有以前的验证来确保CRL适合进行验证。我更新了答案
//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);
}
}
}
}
};