7

我目前正在使用 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),但显然它并没有发挥作用。

编辑:删除过时的 Dropbox 链接

4

4 回答 4

10

正如评论中所建议的,我想出了如何在 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 检查失败,因为它是我们所有的基础设施。

于 2016-07-22T09:38:00.490 回答
4

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 上因以下错误而失败:如何使用 JAVA 检查 X509Certificate 链的吊销状态?

于 2019-06-28T04:01:42.633 回答
2

请注意,禁用吊销检查是一种不好的安全做法。你可以做到,但要确保你知道风险!

@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);
于 2018-12-11T04:27:27.230 回答
1

首先,您可以在 jcontrol(从 1.8 开始)中配置的吊销检查仅适用于appletWebStart下载以及签署者证书检查!对于编程的 https 客户端,您可以使用上面提到的 PKIXRevocationChecker,但根据我的经验,Oracle 实现根本不支持 LDAP CDP 下载。当我遇到这个问题时,我需要使用 CRL 实施完整的证书链检查,并从 LDAP 立即下载 CA 证书,在我的自定义 TrustManager 的 checkXXXX 函数后面......

于 2018-09-24T07:42:45.637 回答