当我们使用以下类org.bouncycastle.cms.CMSSignedData和org.bouncycastle.cms.CMSSignedDataGenerator对数据进行签名时,我应该向文件写入什么以验证签名
非常感谢
我已经编写了代码来实现这一点,但我遇到了异常
public class T2 {
public static String ROOT_ALIAS = "root";
public static String INTERMEDIATE_ALIAS = "intermediate";
public static String END_ENTITY_ALIAS = "end";
public static String PLAIN_TEXT = "Hello World!123";
private static final char[] KEY_PASSWORD = "keyPassword".toCharArray();
public static CMSSignedData signData(KeyStore keyStore,
byte[] plainTextToSign) throws Exception {
// GET THE PRIVATE KEY
PrivateKey key = (PrivateKey) keyStore.getKey(END_ENTITY_ALIAS,
KEY_PASSWORD);
Certificate[] chain = keyStore.getCertificateChain(END_ENTITY_ALIAS);
CertStore certsAndCRLs = CertStore.getInstance("Collection",
new CollectionCertStoreParameters(Arrays.asList(chain)), "BC");
X509Certificate cert = (X509Certificate) chain[0];
// set up the generator
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
gen.addSigner(key, cert, CMSSignedDataGenerator.DIGEST_SHA224);
gen.addCertificatesAndCRLs(certsAndCRLs);
// create the signed-data object
CMSProcessable data = new CMSProcessableByteArray(plainTextToSign);
CMSSignedData signed = gen.generate(data, "BC");
// recreate
signed = new CMSSignedData(data, signed.getEncoded());
// ContentInfo conInf = signed.getContentInfo();
// CMSProcessable sigContent = signed.getSignedContent();
new File("D:\\pkcs7\\encrypted-file.p7b");
FileOutputStream fileOuputStream = new FileOutputStream(
"D:\\pkcs7\\encrypted-file.p7b");
fileOuputStream.write(signed.getEncoded());
// fileOuputStream.flush();
fileOuputStream.close();
return signed;
}
public static boolean verifyData(KeyStore keyStore) throws Exception {
File file = new File("D:\\pkcs7\\encrypted-file.p7b");
FileInputStream fileInputStream = new FileInputStream(file);
byte[] signedByte = new byte[(int) file.length()];
fileInputStream.read(signedByte);
fileInputStream.close();
// verification step
X509Certificate rootCert = (X509Certificate) keyStore
.getCertificate(ROOT_ALIAS);
CMSSignedData signed = new CMSSignedData(signedByte);
if (isValidSignature(signed, rootCert)) {
System.out.println("verification succeeded");
return true;
} else {
System.out.println("verification failed");
}
return false;
}
/**
* Take a CMS SignedData message and a trust anchor and determine if the
* message is signed with a valid signature from a end entity entity
* certificate recognized by the trust anchor rootCert.
*/
@SuppressWarnings("rawtypes")
private static boolean isValidSignature(CMSSignedData signedData,
X509Certificate rootCert) throws Exception {
boolean[] bArr = new boolean[2];
bArr[0] = true;
CertStore certsAndCRLs = signedData.getCertificatesAndCRLs(
"Collection", "BC");
SignerInformationStore signers = signedData.getSignerInfos();
Iterator it = signers.getSigners().iterator();
if (it.hasNext()) {
SignerInformation signer = (SignerInformation) it.next();
SignerId signerConstraints = signer.getSID();
signerConstraints.setKeyUsage(bArr);
PKIXCertPathBuilderResult result = buildPath(rootCert,
signer.getSID(), certsAndCRLs);
return signer.verify(result.getPublicKey(), "BC");
}
return false;
}
/**
* Build a path using the given root as the trust anchor, and the passed in
* end constraints and certificate store.
* <p>
* Note: the path is built with revocation checking turned off.
*/
public static PKIXCertPathBuilderResult buildPath(X509Certificate rootCert,
X509CertSelector endConstraints, CertStore certsAndCRLs)
throws Exception {
CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", "BC");
PKIXBuilderParameters buildParams = new PKIXBuilderParameters(
Collections.singleton(new TrustAnchor(rootCert, null)),
endConstraints);
buildParams.addCertStore(certsAndCRLs);
buildParams.setRevocationEnabled(false);
return (PKIXCertPathBuilderResult) builder.build(buildParams);
}
}