Нужна помощь с крипто-подпрограммами в Java.
Учитывая подпись PKCS # 7, я хочу проверить все сертификаты, которые он содержит, в доверенном хранилище. Я предполагаю, что все сертификаты, содержащиеся в подписи, находятся в правильном порядке для формирования правильного пути сертификата (или цепочки, что угодно), так что
- topmost (# 0) - сертификат подписи;
- следующий (# 1) является промежуточным сертификатом, используется для подписи # 0;
- следующий (# 2) - еще один промежуточный сертификат, используемый для подписи # 1;
- и т. Д.
Последний сертификат (#N) подписан CA.
Вот что мне удалось взломать до сих пор:
// Exception handling skipped for readability
//byte[] signature = ...
pkcs7 = new PKCS7(signature); // `sun.security.pkcs.PKCS7;`
// *** Checking some PKCS#7 parameters here
X509Certificate prevCert = null; // Previous certificate we've found
X509Certificate[] certs = pkcs7.getCertificates(); // `java.security.cert.X509Certificate`
for (int i = 0; i < certs.length; i++) {
// *** Checking certificate validity period here
if (cert != null) {
// Verify previous certificate in chain against this one
prevCert.verify(certs[i].getPublicKey());
}
prevCert = certs[i];
}
//String keyStorePath = ...
KeyStore keyStore = KeyStore.getInstance("JKS"); // `java.security.KeyStore`
keyStore.load(new FileInputStream(keyStorePath), null);
// Get trusted VeriSign class 1 certificate
Certificate caCert = keyStore.getCertificate("verisignclass1ca"); // `java.security.cert.Certificate`
// Verify last certificate against trusted certificate
cert.verify(caCert.getPublicKey());
Так что вопрос - как это можно сделать с помощью стандартных классов Java, таких как CertPath
и друзей? У меня сильное чувство, что я заново изобретаю велосипед. Или, если у кого-то есть пример с библиотекой BouncyCastle, это тоже подойдет.
Бонусный вопрос: как проверить сертификат в доверенном хранилище, чтобы корневой сертификат выбирался автоматически?