无法验证签名 (cmssigneddata) bouncycastle
Cannot verify signature (cmssigneddata) bouncycastle
当我想验证我用 BouncyCastle 制作的签名时,我没有进入 verifySignature
方法的第二个 while
循环。 store.getMatches()
返回一个空数组。
public static CMSSignedData sign() throws Exception {
byte[] file = fileChooser();
store = KeyStore.getInstance(storeType);
FileInputStream in = new FileInputStream(new File(storePathKey));
store.load(in, storePassword);
in.close();
Key priv = store.getKey("Subject", storePassword);
System.out.println(priv.toString() + "priv string");
X509Certificate cert = (X509Certificate) store.geCertificate("Subject");
ContentSigner signer = new JcaContentSignerBuilder(sigAlgo).build((RSAPrivateKey) priv);
CMSTypedData data = new CMSProcessableByteArray(file);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build())
.build(signer, cert));
CMSSignedData sigData = gen.generate(data, true);
return sigData;
}
public static void verifySig(CMSSignedData sigData) throws Exception {
Store store = sigData.getCertificates();
SignerInformationStore signers = sigData.getSignerInfos();
System.out.println(store.toString() + "store");
Collection c = signers.getSigners();
Iterator it = c.iterator();
while (it.hasNext()) {
System.out.println("enter while loop1");
SignerInformation signer = (SignerInformation) it.next();
Collection certCollection = store.getMatches(signer.getSID());
Iterator certIt = certCollection.iterator();
System.out.println(store.getMatches(null) + "collection of certs");
while (certIt.hasNext()) {
System.out.println("enter while loop2");
X509CertificateHolder certHolder = (X509CertificateHolder) certIt.next();
X509Certificate cert = new JcaX509CertificateConverter().getCertificate(certHolder);
if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().build(cert))) {
System.out.println("verified correct");
} else {
System.out.println("not verified");
}
}
}
}
我在 sign()
方法中遗漏了什么吗?
您需要将证书添加到org.bouncycastle.util.CollectionStore
,并将此商店添加到签名。
我正在使用 BouncyCastle 1.56:
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.util.CollectionStore;
// add these lines after gen.addSignerInfoGenerator(...)
// cert is your X509Certificate
X509CertificateHolder holder = new X509CertificateHolder(cert.getEncoded());
CollectionStore<X509CertificateHolder> certStore = new CollectionStore<>(Collections.singletonList(holder));
gen.addCertificates(certStore); // add the store to the signature
当您要添加多个证书时,CollectionStore
很有用。如果你只想添加一个,你也可以这样做:
X509CertificateHolder holder = new X509CertificateHolder(cert.getEncoded());
gen.addCertificate(holder);
我得到的输出:
enter while loop1
[org.bouncycastle.cert.X509CertificateHolder@5bc807a8]collection of certs
enter while loop2
verified correct
当我想验证我用 BouncyCastle 制作的签名时,我没有进入 verifySignature
方法的第二个 while
循环。 store.getMatches()
返回一个空数组。
public static CMSSignedData sign() throws Exception {
byte[] file = fileChooser();
store = KeyStore.getInstance(storeType);
FileInputStream in = new FileInputStream(new File(storePathKey));
store.load(in, storePassword);
in.close();
Key priv = store.getKey("Subject", storePassword);
System.out.println(priv.toString() + "priv string");
X509Certificate cert = (X509Certificate) store.geCertificate("Subject");
ContentSigner signer = new JcaContentSignerBuilder(sigAlgo).build((RSAPrivateKey) priv);
CMSTypedData data = new CMSProcessableByteArray(file);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build())
.build(signer, cert));
CMSSignedData sigData = gen.generate(data, true);
return sigData;
}
public static void verifySig(CMSSignedData sigData) throws Exception {
Store store = sigData.getCertificates();
SignerInformationStore signers = sigData.getSignerInfos();
System.out.println(store.toString() + "store");
Collection c = signers.getSigners();
Iterator it = c.iterator();
while (it.hasNext()) {
System.out.println("enter while loop1");
SignerInformation signer = (SignerInformation) it.next();
Collection certCollection = store.getMatches(signer.getSID());
Iterator certIt = certCollection.iterator();
System.out.println(store.getMatches(null) + "collection of certs");
while (certIt.hasNext()) {
System.out.println("enter while loop2");
X509CertificateHolder certHolder = (X509CertificateHolder) certIt.next();
X509Certificate cert = new JcaX509CertificateConverter().getCertificate(certHolder);
if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().build(cert))) {
System.out.println("verified correct");
} else {
System.out.println("not verified");
}
}
}
}
我在 sign()
方法中遗漏了什么吗?
您需要将证书添加到org.bouncycastle.util.CollectionStore
,并将此商店添加到签名。
我正在使用 BouncyCastle 1.56:
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.util.CollectionStore;
// add these lines after gen.addSignerInfoGenerator(...)
// cert is your X509Certificate
X509CertificateHolder holder = new X509CertificateHolder(cert.getEncoded());
CollectionStore<X509CertificateHolder> certStore = new CollectionStore<>(Collections.singletonList(holder));
gen.addCertificates(certStore); // add the store to the signature
当您要添加多个证书时,CollectionStore
很有用。如果你只想添加一个,你也可以这样做:
X509CertificateHolder holder = new X509CertificateHolder(cert.getEncoded());
gen.addCertificate(holder);
我得到的输出:
enter while loop1
[org.bouncycastle.cert.X509CertificateHolder@5bc807a8]collection of certs
enter while loop2
verified correct