2

Java 11 中是否有一些快速的“声明性”方式,而不是繁琐的手动实现来检查证书是否被吊销?

我尝试使用此答案中的属性: 在 使用此虚拟吊销证书进行身份验证之前检查 Spring-Security 中的 X509 证书吊销状态: 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();
    }
}
4

1 回答 1

3

似乎必须在执行第一个请求之前设置这些选项。

因此,作为独立 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;
            }
        }
    }
}
于 2019-03-26T08:48:39.283 回答