gpt4 book ai didi

java - 在 Java 中验证 PKCS#7 证书

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:07:56 24 4
gpt4 key购买 nike

需要一些有关 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 和 friend )来完成此操作?我有一种强烈的感觉,我正在重新发明一辆自行车。或者,如果有人有 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() 将抛出异常。

文档:ASN1Set , ContentInfo , SignedData .所有其他异国情调的名称和相关文档都可以在 java.security.cert 中找到。

此处没有 SUN 依赖项,只有 BouncyCastle provider library是需要的。

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

关于java - 在 Java 中验证 PKCS#7 证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3166159/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com