在 Java 中需要一些有关加密例程的帮助。
给定 PKCS#7 签名,我想根据受信任的存储验证它包含的所有证书。我假设签名中包含的所有证书都以正确的顺序形成有效的证书路径(或链,等等),所以
- topmost (#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 库的示例,那也可以。
额外问题:如何根据受信任的存储验证证书以便自动选择根证书?