Отзыв OCSP на клиентский сертификат
Как вручную проверить статус отзыва сертификата в java с помощью OCSP, учитывая только клиентский сертификат java.security.cert.X509Certificate? Я не вижу ясного способа сделать это.
В качестве альтернативы, могу ли я сделать tomcat для этого автоматически, и как вы знаете, что ваше решение является истинным?
Ответы
Ответ 1
Я нашел отличное решение:
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 */
Он имеет проверку метода (X509Certificate clientCert, X509Certificate issuerCert), который выполняет трюк!
Ответ 2
Похоже, здесь есть патч для Tomcat, чтобы включить проверку ocsp.
Если вы решите сделать это вручную:
Security.setProperty("ocsp.enable", "true")
Или установите его с помощью аргумента командной строки. Смотрите здесь:
Значение этого свойства равно true или false. Если значение true, проверка OCSP включена при проверке отзыва сертификатов; если false или не установлен, проверка OCSP отключена.
И вот какой код, который я думаю, работает:
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;
}
}
}
Ответ 3
Вот соответствующий код из Jetty 7, который берет массив сертификатов, вытащил из запроса servletRequest и проверяет их через API-интерфейс certpath с помощью OCSP.
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
Ответ 4
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());
}