我目前正在使用SSL编写网络TCP服务器。在生产中,我们最终会要求客户使用证书进行身份验证。
为了在紧急情况下撤销证书,我们还想建立一个CRL。
我的问题是:Java是否开箱即用检查CRL(如果提供证书)或我是否需要手动执行此类检查?
为了进行测试,我准备了一个带有CRL集的证书,但是Java似乎没有尝试验证它(我将它放入本地Web服务器并且没有访问权限)。
我只找到 com.sun.net.ssl.checkRevocation = true VM选项,但显然它不查询CRL。设置为 java.security.debug = certpath 的VM调试不会生成任何输出...
Java似乎在其子系统中有相关的类(例如 java.security.cert.X509CRLSelector ),但它显然没有发挥作用。
我使用Apache Mina作为客户端服务器编写了一个小型的maven风格的项目,它基于密钥/信任库和客户端/服务器的自签名证书初始化SSLContext,可以在这里以ZIP存档的形式下载:https://www.dropbox.com/s/3fqmd1v9mn2a5ve/ssltest.zip?dl=0 < / p>
答案 0 :(得分:8)
我想了解如何在SSLContext中启用CRL检查而不实现自定义验证器,如评论中所示。
主要是通过撤销检查器正确初始化SSLContext的TrustManagers,只有几行,没有自定义检查逻辑,现在自动检查CRL以及验证路径。
这是一个片段......
KeyStore ts = KeyStore.getInstance("JKS");
FileInputStream tfis = new FileInputStream(trustStorePath);
ts.load(tfis, trustStorePass.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
// initialize certification path checking for the offered certificates and revocation checks against CLRs
CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
PKIXRevocationChecker rc = (PKIXRevocationChecker)cpb.getRevocationChecker();
rc.setOptions(EnumSet.of(
PKIXRevocationChecker.Option.PREFER_CRLS, // prefer CLR over OCSP
PKIXRevocationChecker.Option.ONLY_END_ENTITY,
PKIXRevocationChecker.Option.NO_FALLBACK)); // don't fall back to OCSP checking
PKIXBuilderParameters pkixParams = new PKIXBuilderParameters(ts, new X509CertSelector());
pkixParams.addCertPathChecker(rc);
tmf.init( new CertPathTrustManagerParameters(pkixParams) );
// init KeyManagerFactory
kmf.init(...)
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers), tmf.getTrustManagers(), null);
基本上我在我的应用程序中做了我需要的,检查发给客户端的证书是否在我们的CRL中被撤销。只接受检查最终实体并允许CRL检查失败,因为它是我们所有的基础设施。
答案 1 :(得分:2)
请注意,禁用吊销检查是一种不良的安全做法。您可以做到,但是请确保您知道风险!
currently accepted answer的@DoNuT通过设置PKIXRevocationChecker.Option.SOFT_FAIL
来工作,即使撤销检查失败,验证器也不会引发异常。以下答案完全禁用了吊销检查,因此,如果您根本不需要验证,它会更快。这是因为执行吊销检查需要联系CRL分发点或OCSP服务器,如果您不希望这样做,则无需支付任何费用。
您可以简单地在类型setRevocationEnabled(false)
的对象上使用PKIXBuilderParameters
。
// Initialize "anchors" to trusted certificates
// Initialize "selector" to the certificate you want to validate
PKIXBuilderParameters pbParams = new PKIXBuilderParameters(anchors, selector);
pbParams.setRevocationEnabled(false); // disable revocation check
CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
CertPathBuilderResult cpbResult = cpb.build(pbParams);
CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
CertPathValidatorResult result = cpv.validate(cpbResult.getCertPath(), pbParams);
System.out.println(result);
答案 2 :(得分:1)
首先,您可以在jcontrol(从1.8开始)中配置的吊销检查仅适用于 applet 和 WebStart 下载以及签名者证书检查! 对于已编程的https客户端,您可以使用上面提到的PKIXRevocationChecker,但是根据我的经验,Oracle实施根本不支持LDAP CDP下载。 遇到此问题时,我需要在自定义TrustManager的checkXXXX函数后面,使用CRL和从LDAP即时下载CA证书来实施完整的证书链检查。
答案 3 :(得分:1)
OCSP适合您吗?
下面的代码为我启用了OCSP:
// for debugging:
System.setProperty("javax.net.debug", "all");
System.setProperty("java.security.debug", "all");
System.setProperty("com.sun.net.ssl.checkRevocation", "true");
Security.setProperty("ocsp.enable", "true");
在CRL上由于以下错误而失败:How to check revocation status of X509Certificate chain using JAVA?