使用bouncycastle正确的方式签署和验证签名

编程入门 行业动态 更新时间:2024-10-15 02:27:03
本文介绍了使用bouncycastle正确的方式签署和验证签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在使用 bcmail-jdk16-1.46.jar 和 bcprov-jdk16-1.46.jar (Bouncycastle图书馆)签署字符串,然后验证签名。

I am using bcmail-jdk16-1.46.jar and bcprov-jdk16-1.46.jar (Bouncycastle libraries) to sign a string and then verify the signature.

这是我的代码签署字符串:

This is my code to sign a string:

package my.package; import java.io.FileInputStream; import java.security.Key; import java.security.KeyStore; import java.security.PrivateKey; import java.security.Security; import java.security.Signature; 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 sun.misc.BASE64Encoder; public class SignMessage { static final String KEYSTORE_FILE = "keys/certificates.p12"; static final String KEYSTORE_INSTANCE = "PKCS12"; static final String KEYSTORE_PWD = "test"; static final String KEYSTORE_ALIAS = "Key1"; public static void main(String[] args) throws Exception { String text = "This is a message"; Security.addProvider(new BouncyCastleProvider()); KeyStore ks = KeyStore.getInstance(KEYSTORE_INSTANCE); ks.load(new FileInputStream(KEYSTORE_FILE), KEYSTORE_PWD.toCharArray()); Key key = ks.getKey(KEYSTORE_ALIAS, KEYSTORE_PWD.toCharArray()); //Sign PrivateKey privKey = (PrivateKey) key; Signature signature = Signature.getInstance("SHA1WithRSA", "BC"); signature.initSign(privKey); signature.update(text.getBytes()); //Build CMS X509Certificate cert = (X509Certificate) ks.getCertificate(KEYSTORE_ALIAS); List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray(signature.sign()); certList.add(cert); Store certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privKey); gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(sha1Signer, cert)); gen.addCertificates(certs); CMSSignedData sigData = gen.generate(msg, false); BASE64Encoder encoder = new BASE64Encoder(); String signedContent = encoder.encode((byte[]) sigData.getSignedContent().getContent()); System.out.println("Signed content: " + signedContent + "\n"); String envelopedData = encoder.encode(sigData.getEncoded()); System.out.println("Enveloped data: " + envelopedData); } }

现在,$在这个过程中,将使用EnvelopedData 输出验证 签名

Now, the EnvelopedData output will be used in the process to verify the signature by this way:

package my.package; import java.security.Security; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Iterator; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Store; import org.bouncycastle.util.encoders.Base64; public class VerifySignature { public static void main(String[] args) throws Exception { String envelopedData = "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIAwggLQMIIC" + "OQIEQ479uzANBgkqhkiG9w0BAQUFADCBrjEmMCQGCSqGSIb3DQEJARYXcm9zZXR0YW5ldEBtZW5k" + "ZWxzb24uZGUxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIEwZCZXJsaW4xDzANBgNVBAcTBkJlcmxpbjEi" + "MCAGA1UEChMZbWVuZGVsc29uLWUtY29tbWVyY2UgR21iSDEiMCAGA1UECxMZbWVuZGVsc29uLWUt" + "Y29tbWVyY2UgR21iSDENMAsGA1UEAxMEbWVuZDAeFw0wNTEyMDExMzQyMTlaFw0xOTA4MTAxMzQy" + "MTlaMIGuMSYwJAYJKoZIhvcNAQkBFhdyb3NldHRhbmV0QG1lbmRlbHNvbi5kZTELMAkGA1UEBhMC" + "REUxDzANBgNVBAgTBkJlcmxpbjEPMA0GA1UEBxMGQmVybGluMSIwIAYDVQQKExltZW5kZWxzb24t" + "ZS1jb21tZXJjZSBHbWJIMSIwIAYDVQQLExltZW5kZWxzb24tZS1jb21tZXJjZSBHbWJIMQ0wCwYD" + "VQQDEwRtZW5kMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+X1g6JvbdwJI6mQMNT41GcycH" + "UbwCFWKJ4qHDaHffz3n4h+uQJJoQvc8yLTCfnl109GB0yL2Y5YQtTohOS9IwyyMWBhh77WJtCN8r" + "dOfD2DW17877te+NlpugRvg6eOH6np9Vn3RZODVxxTyyJ8pI8VMnn13YeyMMw7VVaEO5hQIDAQAB" + "MA0GCSqGSIb3DQEBBQUAA4GBALwOIc/rWMAANdEh/GgO/DSkVMwxM5UBr3TkYbLU/5jg0Lwj3Y++" + "KhumYSrxnYewSLqK+JXA4Os9NJ+b3eZRZnnYQ9eKeUZgdE/QP9XE04y8WL6ZHLB4sDnmsgVaTU+p" + "0lFyH0Te9NyPBG0J88109CXKdXCTSN5gq0S1CfYn0staAAAxggG9MIIBuQIBATCBtzCBrjEmMCQG" + "CSqGSIb3DQEJARYXcm9zZXR0YW5ldEBtZW5kZWxzb24uZGUxCzAJBgNVBAYTAkRFMQ8wDQYDVQQI" + "EwZCZXJsaW4xDzANBgNVBAcTBkJlcmxpbjEiMCAGA1UEChMZbWVuZGVsc29uLWUtY29tbWVyY2Ug" + "R21iSDEiMCAGA1UECxMZbWVuZGVsc29uLWUtY29tbWVyY2UgR21iSDENMAsGA1UEAxMEbWVuZAIE" + "Q479uzAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUx" + "DxcNMTMwNTIxMDE1MDUzWjAjBgkqhkiG9w0BCQQxFgQU8mE6gw6iudxLUc9379lWK0lUSWcwDQYJ" + "KoZIhvcNAQEBBQAEgYB5mVhqJu1iX9nUqfqk7hTYJb1lR/hQiCaxruEuInkuVTglYuyzivZjAR54" + "zx7Cfm5lkcRyyxQ35ztqoq/V5JzBa+dYkisKcHGptJX3CbmmDIa1s65mEye4eLS4MTBvXCNCUTb9" + "STYSWvr4VPenN80mbpqSS6JpVxjM0gF3QTAhHwAAAAAAAA=="; Security.addProvider(new BouncyCastleProvider()); CMSSignedData cms = new CMSSignedData(Base64.decode(envelopedData.getBytes())); Store store = cms.getCertificates(); SignerInformationStore signers = cms.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation) it.next(); Collection certCollection = store.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder certHolder = (X509CertificateHolder) certIt.next(); X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder); if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert))) { System.out.println("verified"); } } } }

由于以下异常

Everything works good until signer.verify(..) due to the following Exception:

Exception in thread "main" org.bouncycastle.cms.CMSSignerDigestMismatchException: message-digest attribute value does not match calculated value at org.bouncycastle.cms.SignerInformation.doVerify(Unknown Source) at org.bouncycastle.cms.SignerInformation.verify(Unknown Source) at my.package.VerifySignature.main(VerifySignature.java:64)

我真的不知道我在做什么错误。有人可以给我一些发生的情况吗?

And I really don't know what I am doing wrong. Can someone please give me a hint of what is happening?

PS 。如果有人想要测试上述代码,您将需要测试证书文件我正在使用复制所有这一切,只需从这里下载/保存:

PS. If someone wants to test the above code, you will need the test certificate file I am using to replicate all this, just download/save it from here:

dl.dropboxusercontent/u/15208254/keys/certificates.p12

推荐答案

gen.generate(msg, false)

表示签名数据未封装在签名中。如果你想创建一个分离的签名,这是很好的,但它的确意味着当你去验证SignedData时,你必须使用CMSSignedData构造函数来获取数据副本 - 在这种情况下,代码是使用单个必须承担签名数据的参数构造函数被封装(因此在这种情况下将为空),结果是验证尝试失败。

means the signed data is not encapsulated in the signature. This is fine if you want to create a detached signature, but it does mean that when you go to verify the SignedData you have to use the CMSSignedData constructor that takes a copy of the data as well - in this case the code is using the single argument constructor which has to assume the signed data was encapsulated (so for this case will be empty), with the result that the attempt at verification is failing.

更多推荐

使用bouncycastle正确的方式签署和验证签名

本文发布于:2023-10-28 04:32:47,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1535531.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:正确   方式   bouncycastle

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!