我目前正在使用 SSL 编写网络 TCP 服务器。在生产中,我们最终会要求客户使用证书进行身份验证。
为了在紧急情况下吊销证书,我们还想建立一个CRL。
我的问题是:Java 是开箱即用地检查 CRL(如果随证书一起提供)还是我需要手动执行此类检查?
为了测试,我准备了一个带有 CRL 集的证书,但 Java 似乎没有尝试验证它(我将它放入本地 Web 服务器,但无法访问)。
我只找到了 com.sun.net.ssl.checkRevocation=true VM 选项,但显然它不会查询 CRL。 VM 调试设置为 java.security.debug=certpath 也不会生成任何输出...
Java 似乎在其子系统中有相关的类(例如 java.security.cert.X509CRLSelector),但显然它没有发挥作用。
编辑:删除过时的 Dropbox 链接
最佳答案
我想出了如何在不实现自定义 validator 的情况下在 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 检查失败,因为它是我们所有的基础设施。
关于java - TCP 套接字 - Java SSL 证书吊销检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38301283/