在Java中验证PKCS#7证书

Java中需要有关加密例程的帮助。

给定PKCS#7签名,我想针对受信任的存储验证它包含的所有证书。我假设签名中包含的所有证书均以正确的顺序形成有效的证书路径(或链,无论如何),因此

  • 最上面的(#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库提供示例,那也可以。

额外的问题:如何针对受信任的存储验证证书,以便自动选择根证书?

回答:

自己找到解决方案。因此,这是如何针对受信任的存储提取和验证证书链的方法(为便于阅读,跳过了异常处理):

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() 如果验证失败,将抛出异常。

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

这里没有SUN依赖项,仅需要BouncyCastle提供程序库。

以上是 在Java中验证PKCS#7证书 的全部内容, 来源链接: utcz.com/qa/425629.html

回到顶部