Форум КриптоПро
»
Средства криптографической защиты информации
»
КриптоПро JCP, JavaTLS
»
JCSP получить CertPath просроченного сертификата с проверкой отзыва offline
Статус: Участник
Группы: Участники
Зарегистрирован: 22.01.2019(UTC) Сообщений: 22   Откуда: Санкт-Петербург Сказал «Спасибо»: 7 раз
|
Добрый день! Есть просроченный сертификат expired.cer (до 31 мая 2025), есть сертификат УЦ действующий ca.cer, есть список отзыва ca.crl (c 1 июня по 8 июня 2025). Сертификат expired.cer в списке отозванных отсутствует. Пытаюсь построить цепочку просроченного сертификата оффлайн на дату, когда еще сертификат дейстовал (в примере 28 мая 2025). Ожидал получил цепочку, но получаю ошибку: Цитата: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:148) at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:129) at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297) at ru.CryptoPro.reprov.CPCertPathBuilder.engineBuild(Unknown Source) at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297) at certpath.CertPathTest.main(CertPathTest.java:84)
Программа получения цепочки: Код:
package certpath;
import java.security.KeyStore;
import java.security.Security;
import java.security.cert.CertPath;
import java.security.cert.CertPathBuilder;
import java.security.cert.CertPathBuilderResult;
import java.security.cert.CertStore;
import java.security.cert.CertificateFactory;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509CRL;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import ru.CryptoPro.Crypto.CryptoProvider;
import ru.CryptoPro.JCP.JCP;
import ru.CryptoPro.JCSP.JCSP;
public class CertPathTest {
public static void main(String[] args) {
try {
System.setProperty("com.sun.security.enableCRLDP", "false");
System.setProperty("com.sun.security.enableAIAcaIssuers", "false");
System.setProperty("com.ibm.security.enableCRLDP", "false");
System.setProperty("ru.CryptoPro.reprov.enableAIAcaIssuers", "false");
Security.removeProvider(JCSP.PROVIDER_NAME);
Security.addProvider(new JCSP());
Security.removeProvider(JCP.PROVIDER_NAME);
Security.addProvider(new JCP());
Security.removeProvider(ru.CryptoPro.reprov.RevCheck.PROVIDER_NAME);
Security.addProvider(new ru.CryptoPro.reprov.RevCheck());
Security.removeProvider(CryptoProvider.PROVIDER_NAME);
Security.addProvider(new CryptoProvider());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
List<TrustManager> trustManagers = Arrays.asList(trustManagerFactory.getTrustManagers());
Set<X509Certificate> cacerts = new HashSet<>(trustManagers.stream().filter(X509TrustManager.class::isInstance)
.map(X509TrustManager.class::cast).map(trustManager -> Arrays.asList(trustManager.getAcceptedIssuers()))
.flatMap(Collection::stream).toList());
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) certificateFactory
.generateCertificate(CertPathTest.class.getResourceAsStream("expired.cer"));
X509Certificate caCert = (X509Certificate) certificateFactory
.generateCertificate(CertPathTest.class.getResourceAsStream("ca.cer"));
X509CRL caCRL = (X509CRL) certificateFactory.generateCRL(CertPathTest.class.getResourceAsStream("ca.crl"));
if( !cacerts.contains(caCert) ) {
throw new IllegalStateException("ca.cer it not trust ca certificate");
}
Set<TrustAnchor> trustAnchors = Collections.singleton(new TrustAnchor(caCert, null));
X509CertSelector targetConstraints = new X509CertSelector();
targetConstraints.setCertificate(cert);
PKIXBuilderParameters pkixBuilderParams = new PKIXBuilderParameters(trustAnchors, targetConstraints);
pkixBuilderParams.addCertStore(
CertStore.getInstance("Collection", new CollectionCertStoreParameters(Collections.singleton(caCRL))));
pkixBuilderParams.setRevocationEnabled(true);
pkixBuilderParams.setDate(Date.from(LocalDate.parse("2025-05-28").atStartOfDay(ZoneOffset.UTC).toInstant()));
CertPathBuilder certPathBuilder = CertPathBuilder.getInstance("CPPKIX");
CertPathBuilderResult certPathBuilderResult = certPathBuilder.build(pkixBuilderParams);
CertPath certPath = certPathBuilderResult.getCertPath();
certPath.getCertificates().forEach(c->{
X509Certificate x509= (X509Certificate) c;
System.out.println(x509.getSubjectX500Principal());
});
} catch (Exception e) {
System.out.println("Cannot get certificate path");
e.printStackTrace();
}
}
}
Я что-то упустил? Или я должен предоставить CRL на дату проверки отзыва, поскольку при включенном режиме отладки certpath -Djava.security.debug=certpath я вижу: certpath: X509CRLSelector.match: update out-of-range А если посмотреть исходники OpenJDK: Код:
/* match on dateAndTime */
if (dateAndTime != null) {
Date crlThisUpdate = xcrl.getThisUpdate();
Date nextUpdate = xcrl.getNextUpdate();
if (nextUpdate == null) {
if (debug != null) {
debug.println("X509CRLSelector.match: nextUpdate null");
}
return false;
}
Date nowPlusSkew = dateAndTime;
Date nowMinusSkew = dateAndTime;
if (skew > 0) {
nowPlusSkew = new Date(dateAndTime.getTime() + skew);
nowMinusSkew = new Date(dateAndTime.getTime() - skew);
}
// Check that the test date is within the validity interval:
// [ thisUpdate - MAX_CLOCK_SKEW,
// nextUpdate + MAX_CLOCK_SKEW ]
if (nowMinusSkew.after(nextUpdate)
|| nowPlusSkew.before(crlThisUpdate)) {
if (debug != null) {
debug.println("X509CRLSelector.match: update out-of-range");
}
return false;
}
}
Получается он отвергает мой CRL. А отвергает он потому что КриптоПро устанавливает дату для X509CRLSelector  crl.JPG (158kb) загружен 5 раз(а).А надо ли устанавливать дату для X509CRLSelector? Ведь CRL это накопительный список с фиксацией даты отзыва. Зачем требуется CRL именно на дату построения цепочку и проверки отзыва? Ведь если я предоставлю более новый CRL это не изменит информации о дате отзыва того или иного сертификата? Отредактировано пользователем 5 июня 2025 г. 17:40:45(UTC)
| Причина: Не указана
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 22.01.2019(UTC) Сообщений: 22   Откуда: Санкт-Петербург Сказал «Спасибо»: 7 раз
|
Отвергать CRL старее даты проверки - это нормально, но почему отвергать CRL новее даты проверки? Какая здесь логика? Нашел старое обсуждение https://www.cryptopro.ru...ts&m=79915#post79915 Получается, что я должен хранить все выпуски CRL и на определенную дату подставлять выпуск списка отзыва, который включает дату проверки между датой выпуска и датой следующего выпуска? Я правильно понимаю? Вообщем, в итоге создал свою реализацию CollectionCertStore, где сбрасываю дату в X509CRLSelector-e перед вызовом match-a, зарегистрировал ее в своем провайдере и теперь получаю цепочку на любую дату с актуальным CRL. Перспектива хранить все выпуску CRL меня особо не греет. Спасибо за внимание! :) Отредактировано пользователем 5 июня 2025 г. 17:40:30(UTC)
| Причина: Не указана
|
|
|
|
Форум КриптоПро
»
Средства криптографической защиты информации
»
КриптоПро JCP, JavaTLS
»
JCSP получить CertPath просроченного сертификата с проверкой отзыва offline
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close