在Java中验证PKCS#7证书 [英] Verifying PKCS#7 certificates in Java

查看:954
本文介绍了在Java中验证PKCS#7证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

需要对Java中的crypto例程有所帮助。

Need some help with crypto routines in Java.

给定一个PKCS#7签名,我想验证它对可信存储库包含的所有证书。我假设签名中包含的所有证书都以正确的顺序形成有效的证书路径(或链,无论什么),以便

Given a PKCS#7 signature, I want to verify all certificates it contains against a trusted store. I assume that all certificates contained in signature are in the correct order to form a valid certificate path (or chain, whatever), so that


  • (#0)是签名证书;

  • 下一个(#1)是用于签名#0的中间证书;

  • next一个(#2)是另一个中间证书,用于签名#1;

  • 等。

  • topmost (#0) is a signing certificate;
  • next one (#1) is an intermediate certificate, used to sign #0;
  • next one (#2) is another intermediate certificate, used to sign #1;
  • and so on.

最后一个证书(#N)由CA签名。

The last certificate (#N) is signed by CA.

这是我到目前为止所设计的:

That's what I've managed to hack so far:

// 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 和朋友?我有一种强烈的感觉,我重新发明了一辆自行车。

So the question is -- how can this be done using standard Java classes like CertPath and friends? I have a strong feeling I'm re-inventing a bicycle. Or, if someone has an example with BouncyCastle library, that would also be fine.

奖金问题:如何针对受信任的商店验证证书,以便选择根证书(如果有的话),或者如果有人使用BouncyCastle库的例子,自动?

Bonus question: how to verify a certificate against a trusted store so that root certificate is selected automatically?

推荐答案

自己找到解决方案。因此,下面是如何提取和验证证书链对可信存储(为了可读性而跳过异常处理):

Found the solution myself. So, here's how one can extract and validate a certificate chain against the trusted store (exception handling skipped for readability):

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提供程序库

No SUN-dependencies here, only BouncyCastle provider library is needed.

问题(尤其是答案)也可以帮助。

This question (and especially an answer) may help too.

这篇关于在Java中验证PKCS#7证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆