Java SSL 证书吊销检查
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38301283/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java SSL Certificate Revocation Checking
提问by DoNuT
I'm currently writing a network TCP server using SSL. In production, we'll finally require clients to authenticate with a certificate.
我目前正在使用 SSL 编写网络 TCP 服务器。在生产中,我们最终会要求客户端使用证书进行身份验证。
In order to revoke certificates in case of a emergency, we would also like to establish a CRL.
为了在紧急情况下撤销证书,我们还想建立一个 CRL。
My question is: Does Java check CRLs (if provided with the certificate) out of the box or do I need to manually implement such checks?
我的问题是:Java 是否开箱即用地检查 CRL(如果提供了证书),或者我是否需要手动实施此类检查?
For testing, I prepared a certificate with a CRL set but Java does not seem to try to validate it (I dropped it into a local web server and there's no access).
为了测试,我准备了一个带有 CRL 集的证书,但 Java 似乎没有尝试验证它(我将它放入本地 Web 服务器并且无法访问)。
I only found the com.sun.net.ssl.checkRevocation=trueVM option, but apparently it doesn't query the CRL. VM debugging set to java.security.debug=certpathdoes not generate any output, either...
我只找到了com.sun.net.ssl.checkRevocation=trueVM 选项,但显然它没有查询 CRL。VM 调试设置为java.security.debug=certpath也不会生成任何输出...
Java seems to have related classes in its subsystems (e.g. java.security.cert.X509CRLSelector), but it does not come into play, obviously.
Java 的子系统中似乎有相关的类(例如java.security.cert.X509CRLSelector),但显然它并没有发挥作用。
I wrote a small maven-style project using Apache Mina as client server that initializes a SSLContext based on key/truststores and self-signed certificates for client/server which can be downloaded here as ZIP archive: https://www.dropbox.com/s/3fqmd1v9mn2a5ve/ssltest.zip?dl=0
我使用 Apache Mina 作为客户端服务器编写了一个小型 maven 风格的项目,该项目基于密钥/信任库和客户端/服务器的自签名证书初始化 SSLContext,可以在此处作为 ZIP 存档下载:https: //www.dropbox.com /s/3fqmd1v9mn2a5ve/ssltest.zip?dl=0
回答by DoNuT
I figured how to enable CRL checking within a SSLContext without implementing a custom validator, as suggested in the comments.
我想出了如何在 SSLContext 中启用 CRL 检查而不实现自定义验证器,如评论中所建议的。
It is mainly about properly initializing the SSLContext's TrustManagers with a revocation checker, only a few lines, no custom check logic and the CRL is now checked automatically as well as the verification path.
它主要是关于使用撤销检查器正确初始化 SSLContext 的 TrustManagers,只有几行,没有自定义检查逻辑,现在自动检查 CRL 以及验证路径。
Here's a snippet...
这是一个片段...
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);
That essentially did what I needed in my application, checking whether a certificate issued to a client is revoked in our CRL. Only checking the end entity and allowing the CRL check to fail is accepted because its all our infrastructure.
这基本上完成了我在应用程序中的需要,检查颁发给客户的证书是否在我们的 CRL 中被撤销。只接受检查终端实体并允许 CRL 检查失败,因为它是我们所有的基础设施。
回答by fishautumn
Is OCSP OK for you?
OCSP 适合您吗?
bellow code enables OCSP for me:
下面的代码为我启用了 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");
failed on CRL for errors like: How to check revocation status of X509Certificate chain using JAVA?
CRL 因以下错误而失败:如何使用 JAVA 检查 X509Certificate 链的吊销状态?
回答by M.S. Dousti
Notice that disabling revocation checking is a bad security practice. You can do it, but make sure you know the risk!
请注意,禁用吊销检查是一种糟糕的安全做法。你可以做到,但要确保你知道风险!
The currently accepted answerby @DoNuTworks by setting PKIXRevocationChecker.Option.SOFT_FAIL
, which causes the validator not to throw an exception even if revocation checking fails. The following answer disables revocation checking altogether, thus it is faster in case you don't want validation at all. This is because performing revocation checks needs contacting CRL distribution points or OCSP servers, and if you don't want that, you need not pay the price.
在目前接受的答案被@DoNuT的工作方式设置PKIXRevocationChecker.Option.SOFT_FAIL
,从而导致验证不扔即使吊销检查失败的异常。以下答案完全禁用吊销检查,因此如果您根本不需要验证,它会更快。这是因为执行吊销检查需要联系 CRL 分发点或 OCSP 服务器,如果您不想这样做,则无需为此付出代价。
You can simply use setRevocationEnabled(false)
on an object of type PKIXBuilderParameters
.
您可以简单地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);
回答by László Báthory
First of all, the revocation checking that you can configure in jcontrol (from 1.8) applies only for appletand WebStartdownloads and signer certificate checks ! For a programmed https client you can use the PKIXRevocationChecker mentioned above, but by my experience the Oracle implementation doesnt support LDAP CDP downloads at all. When I had this problem I needed to implement the full certificate chain check with CRL and immediate CA cert downloads from LDAP, behind my custom TrustManager's checkXXXX functions...
首先,您可以在 jcontrol(从 1.8 开始)中配置的撤销检查仅适用于小程序和WebStart下载以及签名者证书检查!对于已编程的 https 客户端,您可以使用上面提到的 PKIXRevocationChecker,但根据我的经验,Oracle 实现根本不支持 LDAP CDP 下载。当我遇到这个问题时,我需要在我的自定义 TrustManager 的 checkXXXX 函数后面使用 CRL 和立即从 LDAP 下载 CA 证书来实现完整的证书链检查......