java 客户端证书上的 OCSP 吊销

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5161504/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 09:45:39  来源:igfitidea点击:

OCSP Revocation on client certificate

javasecuritytomcatx509certificateocsp

提问by gtrak

How do I manually check for certificate revocation status in java using OCSP, given just a client's java.security.cert.X509Certificate? I can't see a clear way to do it.

仅给定客户端的 java.security.cert.X509Certificate,如何使用 OCSP 手动检查 Java 中的证书吊销状态?我看不到明确的方法。

Alternatively, can I make tomcat do it for me automatically, and how do you know your solution to be true?

或者,我可以让 tomcat 自动为我做,你怎么知道你的解决方案是真的?

采纳答案by gtrak

I found a most excellent solution:

我找到了一个最优秀的解决方案:

http://www.docjar.com/html/api/sun/security/provider/certpath/OCSP.java.html

http://www.docjar.com/html/api/sun/security/provider/certpath/OCSP.java.html

        /**
   54    * This is a class that checks the revocation status of a certificate(s) using
   55    * OCSP. It is not a PKIXCertPathChecker and therefore can be used outside of
   56    * the CertPathValidator framework. It is useful when you want to
   57    * just check the revocation status of a certificate, and you don't want to
   58    * incur the overhead of validating all of the certificates in the
   59    * associated certificate chain.
   60    *
   61    * @author Sean Mullan
   62    */

It has a method check(X509Certificate clientCert, X509Certificate issuerCert) that does the trick!

它有一个方法检查(X509Certificate clientCert,X509Certificate issuerCert)可以解决问题!

回答by gtrak

Here's the relevant code from Jetty 7 that takes an array of certificates pulled from the servletRequest request and validates them via the certpath API with OCSP.

这是来自 Jetty 7 的相关代码,它采用从 servletRequest 请求中提取的一系列证书,并使用 OCSP 通过 certpath API 验证它们。

http://grepcode.com/file/repo1.maven.org/maven2/org.eclipse.jetty/jetty-util/7.4.0.v20110414/org/eclipse/jetty/util/security/CertificateValidator.java#189

http://grepcode.com/file/repo1.maven.org/maven2/org.eclipse.jetty/jetty-util/7.4.0.v20110414/org/eclipse/jetty/util/security/CertificateValidator.java#189

回答by Bozho

It appears there is a patch for Tomcat hereto enable ocsp validation.

看来这里有一个Tomcat 补丁来启用 ocsp 验证。

If you choose to do it manually:

如果您选择手动执行此操作:

Security.setProperty("ocsp.enable", "true")

Or set it via a command-line argument. See here:

或者通过命令行参数设置它。见这里

This property's value is either true or false. If true, OCSP checking is enabled when doing certificate revocation checking; if false or not set, OCSP checking is disabled.

该属性的值为真或假。如果为 true,则在进行证书吊销检查时启用 OCSP 检查;如果为 false 或未设置,则禁用 OCSP 检查。

And here's some code that I think works:

这是我认为有效的一些代码:

interface ValidationStrategy {
    boolean validate(X509Certificate certificate, CertPath certPath,
            PKIXParameters parameters) throws GeneralSecurityException;
}


class SunOCSPValidationStrategy implements ValidationStrategy {
    @Override
    public boolean validate(X509Certificate certificate, CertPath certPath,
            PKIXParameters parameters) throws GeneralSecurityException {
        try {
            CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
            PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) cpv
                    .validate(certPath, parameters);
            Signature.LOG.debug("Validation result is: " + result);
            return true; // if no exception is thrown
        } catch (CertPathValidatorException cpve) {

            // if the exception is (or is caused by)
            // CertificateRevokedException, return false;
            // otherwise re-throw, because this indicates a failure to perform
            // the validation
            Throwable cause = ExceptionUtils.getRootCause(cpve);
            Class<? extends Throwable> exceptionClass = cause != null ? cause.getClass()
                    : cpve.getClass();
            if (exceptionClass.getSimpleName().equals("CertificateRevokedException")) {
                return false;
            }
            throw cpve;
        }
    }

}

回答by manish

import org.bouncycastle.util.io.pem.PemReader;
import sun.security.provider.certpath.OCSP;
import sun.security.x509.X509CertImpl;
import java.io.IOException;
import java.io.StringReader;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Date;

public void test() throws IOException, CertPathValidatorException, java.security.cert.CertificateException {
        X509Certificate userCert = getX509Cert("path_to_user_cert");
        X509Certificate caCert = getX509Cert("path_to_CA_cert");
        OCSP.RevocationStatus ocsp = OCSP.check(userCert, caCert, URI.create("URL to OCSP, but this can be read from USER Cert(AuthorityInfoAccess) As well"), caCert, new Date());
        System.out.println(ocsp);
    }

    private X509CertImpl getX509Cert(final String path) throws CertificateException, IOException {
        return new X509CertImpl(
                new PemReader(
                        new StringReader(
                                new String(
                                        Files.readAllBytes(
                                                Paths.get(path)))))
                        .readPemObject()
                        .getContent());
    }