当我们使用以下类对数据进行签名时,我应该写什么来验证签名 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);
}
}
答案 0 :(得分:0)
当签名包装时,您不需要向文件写入任何内容 - 签名操作的产物是包含签名包的数据。请注意,处理原始无符号数据的应用程序无法直接处理此类签名数据。例如。如果使用包装PKCS#7 / CMS签名对PDF文档进行签名,则Adobe Reader将无法直接打开签名数据(直到签名被删除)。通过将签名数据提供给验证程序来验证签名。
使用分离签名时,签名操作的产品是签名块本身,您可以将其存储在单独的文件中,或作为备用数据流存储在某些文件系统上或数据库中的单独字段中。在这种情况下,您的原始数据保持不变。通过将原始数据和签名块馈送到验证过程来验证签名。