Проверка сертификатов PKCS#7 в Java

Нуждаюсь в некоторой помощи с crypto стандартными программами в Java.

Учитывая подпись PKCS#7, я хочу проверить все сертификаты, которые она содержит против доверяемого хранилища. Я предполагаю, что все сертификаты, содержавшиеся в подписи, должны в правильном порядке сформировать допустимый путь сертификата (или цепочка, безотносительно), так, чтобы

  • самый верхний (#0) сертификат подписания;
  • следующий один (#1) промежуточный сертификат, привыкший к знаку № 0;
  • следующий один (#2) другой промежуточный сертификат, привыкший к знаку № 1;
  • и так далее.

Последний сертификат (#N) подписывается Приблизительно.

Это - то, что мне удалось взломать до сих пор:

// 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, которая была бы также прекрасна.

Вопрос о премии: как проверить сертификат против доверяемого хранилища так, чтобы корневой сертификат был выбран автоматически?

7
задан hudolejev 2 July 2010 в 13:39
поделиться

2 ответа

Я нашел решение самостоятельно. Итак, вот как можно извлечь и проверить цепочку сертификатов по отношению к доверенному хранилищу (обработка исключений пропущена для удобства чтения):

CertificateFactory cf = CertificateFactory.getInstance("X.509");

// Get ContentInfo
//byte[] signature = ... // PKCS#7 signature bytes
InputStream signatureIn = new ByteArrayInputStream(signature);
DERObject obj = new ASN1InputStream(signatureIn).readObject();
ContentInfo contentInfo = ContentInfo.getInstance(obj);

// Extract certificates
SignedData signedData = SignedData.getInstance(contentInfo.getContent());
Enumeration certificates = signedData.getCertificates().getObjects();

// Build certificate path
List certList = new ArrayList();
while (certificates.hasMoreElements()) {
    DERObject certObj = (DERObject) certificates.nextElement();
    InputStream in = new ByteArrayInputStream(certObj.getDEREncoded());
    certList.add(cf.generateCertificate(in));
}
CertPath certPath = cf.generateCertPath(certList);

// Load key store
//String keyStorePath = ...
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(keyStorePath), null);

// Set validation parameters
PKIXParameters params = new PKIXParameters(keyStore);
params.setRevocationEnabled(false); // to avoid exception on empty CRL

// Validate certificate path
CertPathValidator validator = CertPathValidator.getInstance("PKIX");
CertPathValidatorResult result = validator.validate(certPath, params);

validate () выдаст исключение, если проверка не удалась.

Документы: ASN1Set , ContentInfo , SignedData . Все другие экзотические имена и связанные с ними документы можно найти в java.security.cert .

Здесь нет SUN-зависимостей, нужна только библиотека поставщика BouncyCastle .

Этот вопрос (и особенно ответ) тоже может помочь.

13
ответ дан 6 December 2019 в 14:00
поделиться

Вам нужна CertificateFactory . Последний пример в документации javadoc делает именно то, что вы хотите.

2
ответ дан 6 December 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: