在Java 11中是否有一些快速的“声明性”方式,而不是繁琐的手动实现,以便检查证书是否被撤销?
我试图使用这个答案的属性:Check X509 certificate revocation status in Spring-Security before authenticating与这个虚拟吊销证书:https://revoked.badssl.com但代码总是接受证书。我做错了什么或者这些属性对于Java 11来说不再实际?如果是这样,我们有其他选择吗?
以下是我的代码:
public static void validateOnCertificateRevocation(boolean check) {
if (check) {
System.setProperty("com.sun.net.ssl.checkRevocation", "true");
System.setProperty("com.sun.security.enableCRLDP", "true");
Security.setProperty("ocsp.enable", "true");
}
try {
new URL("https://revoked.badssl.com").openConnection().connect();
} catch (IOException e) {
e.printStackTrace();
}
}
似乎必须在执行第一个请求之前设置这些选项。
因此,以下代码作为独立的Java程序抛出CertPathValidatorException: Certificate has been revoked
(在Windows上使用OpenJDK 11.0.2 x64进行测试):
public static void main(String[] args) {
validateOnCertificateRevocation(true); // throws CertPathValidatorException
}
但是,以下代码不会导致任何错误/异常:
public static void main(String[] args) {
validateOnCertificateRevocation(false);
validateOnCertificateRevocation(true); // nothing happens
}
您可以看到在处理第一个请求后无效的更改选项。我假设这些选项是在某些证书验证相关类的static { ... }
块中处理的。
如果您仍想在每个请求的基础上启用/禁用证书吊销检查,您可以通过实现自己使用X509TrustManager
的CertPathValidator
来实现此目的(您可以通过PKIXParameters.setRevocationEnabled(boolean)
启用/禁用证书吊销检查)。
或者,有一个全局启用证书吊销检查的解决方案,并显式处理CertificateRevokedException:
private boolean checkOnCertificateRevocation;
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
try {
getDefaultTrustManager().checkServerTrusted(certs, authType);
} catch (CertificateException e) {
if (checkOnCertificateRevocation) {
if (getRootCause(e) instanceof CertificateRevokedException) {
throw e;
}
}
}
}