用JavavalidationPKCS#7证书

在Java中需要一些加密例程的帮助。

鉴于PKCS#7签名,我想validation它包含的所有证书对可信商店。 我假设签名中包含的所有证书都以正确的顺序形成有效的证书路径(或链,无论如何),以便这样做

  • 最顶层(#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()); 

所以问题是 – 如何使用像CertPath和朋友这样的标准Java类来完成这项工作? 我有一种强烈的感觉,我正在重新发明一辆自行车。 或者,如果某人有BouncyCastle库的示例,那也没关系。

红利问题:如何针对受信任的商店validation证书,以便自动选择根证书?

自己找到了解决方案。 因此,以下是如何针对可信存储提取和validation证书链的方法(为了便于阅读而跳过exception处理):

 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); 

如果validation失败, validate()将抛出exception。

文档: ASN1SetContentInfoSignedData 。 所有其他外来名称和相关文档都可以在java.security.cert找到。

此处没有SUN依赖项,只需要BouncyCastle提供程序库 。

这个问题(尤其是答案)也可能有所帮助。

你想要CertificateFactory 。 javadocs中的最后一个例子完全符合你的要求。