使用JAVA中的PKCS#7对数据进行签名

我想使用PKCS#7签署一个文本文件(可能是.exe文件或将来的其他文件)并使用Javavalidation签名。

  1. 我需要知道什么?
  2. 我在哪里可以找到API( .jar和文档)?
  3. 为了签署数据和validation数据,我需要遵循哪些步骤?

如果可能,请提供代码段。

我估计你需要以下2个Bouncy Castlejar来生成PKCS7数字签名:

  • bcprov-jdk15on-147.jar(适用于JDK 1.5 – JDK 1.7)

  • bcmail-jdk15on-147.jar(适用于JDK 1.5 – JDK 1.7)

您可以从这里下载Bouncy Castlejar子。

您需要使用公钥和私钥对设置密钥库。 您只需要私钥来生成数字签名和公钥来validation它。

以下是pkcs7签名内容的方法(为简洁起见,省略了exception处理):

 import java.io.FileInputStream; import java.io.InputStream; import java.security.KeyStore; import java.security.PrivateKey; import java.security.Security; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import org.bouncycastle.cert.jcajce.JcaCertStore; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.CMSTypedData; import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.Store; import org.bouncycastle.util.encoders.Base64; public final class PKCS7Signer { private static final String PATH_TO_KEYSTORE = "/path/to/keyStore"; private static final String KEY_ALIAS_IN_KEYSTORE = "My_Private_Key"; private static final String KEYSTORE_PASSWORD = "MyPassword"; private static final String SIGNATUREALGO = "SHA1withRSA"; public PKCS7Signer() { } KeyStore loadKeyStore() throws Exception { KeyStore keystore = KeyStore.getInstance("JKS"); InputStream is = new FileInputStream(PATH_TO_KEYSTORE); keystore.load(is, KEYSTORE_PASSWORD.toCharArray()); return keystore; } CMSSignedDataGenerator setUpProvider(final KeyStore keystore) throws Exception { Security.addProvider(new BouncyCastleProvider()); Certificate[] certchain = (Certificate[]) keystore.getCertificateChain(KEY_ALIAS_IN_KEYSTORE); final List certlist = new ArrayList(); for (int i = 0, length = certchain == null ? 0 : certchain.length; i < length; i++) { certlist.add(certchain[i]); } Store certstore = new JcaCertStore(certlist); Certificate cert = keystore.getCertificate(KEY_ALIAS_IN_KEYSTORE); ContentSigner signer = new JcaContentSignerBuilder(SIGNATUREALGO).setProvider("BC"). build((PrivateKey) (keystore.getKey(KEY_ALIAS_IN_KEYSTORE, KEYSTORE_PASSWORD.toCharArray()))); CMSSignedDataGenerator generator = new CMSSignedDataGenerator(); generator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC"). build()).build(signer, (X509Certificate) cert)); generator.addCertificates(certstore); return generator; } byte[] signPkcs7(final byte[] content, final CMSSignedDataGenerator generator) throws Exception { CMSTypedData cmsdata = new CMSProcessableByteArray(content); CMSSignedData signeddata = generator.generate(cmsdata, true); return signeddata.getEncoded(); } public static void main(String[] args) throws Exception { PKCS7Signer signer = new PKCS7Signer(); KeyStore keyStore = signer.loadKeyStore(); CMSSignedDataGenerator signatureGenerator = signer.setUpProvider(keyStore); String content = "some bytes to be signed"; byte[] signedBytes = signer.signPkcs7(content.getBytes("UTF-8"), signatureGenerator); System.out.println("Signed Encoded Bytes: " + new String(Base64.encode(signedBytes))); } } 

PKCS#7现在称为CMS(加密消息语法),您需要使用Bouncy Castle PKIX库来创建一个。 它有充足的文档和完善的邮件列表。

我不会提供代码片段,这是违反内部规则的。 先试试自己吧。