Анализ синтаксического анализа и проверки сертификатов Java X509
Я пытаюсь обрабатывать сертификаты X509 в несколько шагов и сталкиваться с несколькими проблемами. Я новичок в JCE, поэтому я пока не полностью обновляюсь.
Мы хотим иметь возможность анализировать несколько разных сертификатов X509 на основе разных кодировок (PEM, DER и PCKS7). Я экспортировал тот же сертификат из https://belgium.be в формате PEM и PCKS7, используя FireFox (сертификат, включая цепочку). Я оставил пару строк, которые не нужны для вопросов
public List<X509Certificate> parse(FileInputStream fis) {
/*
* Generate a X509 Certificate initialized with the data read from the inputstream.
* NOTE: Generation fails when using BufferedInputStream on PKCS7 certificates.
*/
List<X509Certificate> certificates = null;
log.debug("Parsing new certificate.");
certificates = (List<X509Certificate>) cf.generateCertificates(fis);
return certificates;
}
Этот код работает отлично, поскольку я работаю с FileInputStream вместо BufferedInputStream для PCKS7, что довольно странно, я думаю? Но я могу жить с ним.
Следующий шаг - проверить эти цепочки сертификатов.
1) Проверьте, действительно ли все сертификаты имеют действительную дату (легко)
2) Проверять цепочку сертификатов с помощью OCSP (и возвращаться к CRL, если в сертификате нет URL-адреса OCSP). Здесь я не совсем уверен, как с этим справиться.
Я использую Sun JCE, но, похоже, для этого недостаточно документации (в примерах)?
Сначала я сделал простую реализацию, которая проверяет цепочку, не просматривая проверки OCSP/CRL.
private Boolean validateChain(List<X509Certificate> certificates) {
PKIXParameters params;
CertPath certPath;
CertPathValidator certPathValidator;
Boolean valid = Boolean.FALSE;
params = new PKIXParameters(keyStore);
params.setRevocationEnabled(false);
certPath = cf.generateCertPath(certificates);
certPathValidator = CertPathValidator.getInstance("PKIX");
PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)
certPathValidator.validate(certPath, params);
if(null != result) {
valid = Boolean.TRUE;
}
return valid;
}
Это отлично работает для моего сертификата PEM, но не для сертификата PCKS7 (тот же certifcate, который экспортируется только в другом формате).
java.security.cert.CertPathValidatorException: путь не связан ни с одним из привязок доверия.
Единственное различие, которое я могу видеть, заключается в том, что порядок, в котором формируется CertPath, не является тем же самым? Я не мог понять, что происходит не так, поэтому я оставил это на данный момент и продолжал работать с сертификатом PEM, но позвонил на этот ВОПРОС 1;)
То, что я хотел реализовать после этого, было проверкой OCSP.
По-видимому, если я включу OCSP, используя: Security.setProperty( "ocsp.enable", "true" ); и установите params.setRevocationEnabled(true);
он должен иметь возможность находить URL OCSP самостоятельно, но это, похоже, не так. Какая стандартная реализация должна выполняться (ВОПРОС 2)?
java.security.cert.CertPathValidatorException: необходимо указать расположение ответчика OCSP
Пройдя мимо этого, я нашел способ получить URL-адрес OCSP из сертификата с помощью функции AuthorityInfoAccessExtension и т.д.
Но после установки URL-адреса OCSP вручную в свойстве ocsp.url я получаю сообщение java.security.cert.CertPathValidatorException: ошибка ответа OCSP: UNAUTHORIZED
Кажется, что мне не хватает множества необходимых шагов, в то время как многие онлайн-ссылки говорят, что установка свойства ocsp.enable должна быть все, что вам нужно сделать?
Возможно, кто-нибудь из вас, визкиды, не может мне немного пройти через этот процесс? Покажи мне, где я совершенно не прав:)
Следующим шагом будет реализация CRL-проверок, если OCSP не будет найден, если кто-нибудь может указать какой-либо пример или показать мне некоторую документацию по этому поводу, это также будет очень полезно!
Спасибо!
EDIT:
Поскольку он не сам выбирает свойства, я сам пытался установить все свойства, используя следующее:
// Activate OCSP
Security.setProperty("ocsp.enable", "true");
// Activate CRLDP -- no idea what this is
Security.setProperty("com.sun.security.enableCRLDP", "true");
X509Certificate target = (X509Certificate) certPath.getCertificates().get(0);
Security.setProperty("ocsp.responderURL","http://ocsp.pki.belgium.be/");
Security.setProperty("ocsp.responderCertIssuerName", target.getIssuerX500Principal().getName());
Security.setProperty("ocsp.responderCertSubjectName", target.getSubjectX500Principal().getName());
Security.setProperty("ocsp.responderCertSerialNumber", target.getSerialNumber().toString(16));
Что дает исключение:
java.security.cert.CertPathValidatorException: не удается найти сертификат ответчика (устанавливается с использованием свойств безопасности OCSP).
Ответы
Ответ 1
В будущем я отправлю ответ на свой вопрос (частично по крайней мере)
Проверки OCSP и CRL уже реализованы в стандартной реализации Java, и нет необходимости в создании кода или других поставщиков (BC,..). По умолчанию они отключены.
Чтобы включить это, вы должны, по крайней мере, установить два параметра:
(PKIXParameters or PKIXParameterBuilder) params.setRevocationEnabled(true);
Security.setProperty("ocsp.enable", "true");
Это активирует проверку OCSP, когда вы пытаетесь проверить путь к сертификату (PKIXCertPathValidatorResult.validate()).
Если вы хотите добавить резервную проверку для CRL, если нет OCSP, добавьте свойство aditional:
System.setProperty("com.sun.security.enableCRLDP", "true");
Многие из моих проблем происходят из-за того, что мне приходится поддерживать разные форматы сертификатов (PKCS7, PEM). Моя реализация отлично работает для PEM, но поскольку PKCS7 НЕ сохраняет порядок сертификатов в цепочке, это немного сложнее (http://bugs.sun.com/view_bug.do?bug_id=6238093)
X509CertSelector targetConstraints = new X509CertSelector();
targetConstraints.setCertificate(certificates.get(0));
// Here the issue for PKCS7 certificates since they are not ordered,
// but I havent figured out how I can see what the target certificate
// (lowest level) is in the incoming certificates..
PKIXBuilderParameters params = new PKIXBuilderParameters(anchors, targetConstraints);
Надеюсь, что это будет полезно для других людей, возможно, кто-то может пролить свет на то, как найти целевой сертификат в неупорядоченном списке PKCS7?