问题描述
我正在使用 bcmail-jdk16-1.46.jar 和 bcprov-jdk16-1.46.jar (Bouncycastle 库) 签署 string 然后验证 signature.
I vpn free am using bcmail-jdk16-1.46.jar and bcprov-jdk16-1.46.jar (Bouncycastle libraries) to sign a string and then verify the signature.
这是我用来签署 vpn free string free vpn 的 code:
This 免费vpn 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 vpn下载 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 {
vpn free static final String KEYSTORE_FILE = "keys/certificates.p12";
static final String KEYSTORE_INSTANCE = "PKCS12";
vpn下载 static final vpn下载 String KEYSTORE_PWD = "test";
vpn free static final String KEYSTORE_ALIAS = "Key1";
免费vpn下载 public static void main(String[] vpn free 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());
vpn free Key key = ks.getKey(KEYSTORE_ALIAS, KEYSTORE_PWD.toCharArray());
//Sign
PrivateKey privKey = (PrivateKey) key;
vpn下载 Signature signature = Signature.getInstance("SHA1WithRSA", "BC");
免费vpn signature.initSign(privKey);
vpn下载 signature.update(text.getBytes());
//Build CMS
X509Certificate cert = free vpn (X509Certificate) ks.getCertificate(KEYSTORE_ALIAS);
free vpn List vpn下载 certList = new ArrayList();
CMSTypedData msg = new 免费vpn CMSProcessableByteArray(signature.sign());
certList.add(cert);
free vpn Store certs = new JcaCertStore(certList);
vpn free CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
vpn下载 ContentSigner sha1Signer = vpn free new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privKey);
gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(sha1Signer, vpn free cert));
gen.addCertificates(certs);
CMSSignedData sigData = gen.generate(msg, false);
vpn下载 BASE64Encoder encoder = vpn free new BASE64Encoder();
String vpn free signedContent = encoder.encode((byte[]) sigData.getSignedContent().getContent());
System.out.println("Signed content: " + signedContent + "
");
String envelopedData = encoder.encode(sigData.getEncoded());
System.out.println("Enveloped data: " + envelopedData);
免费vpn }
}
现在,EnvelopedData 输出将用于verify signature:
Now, the EnvelopedData vpn下载 output will be used in the process to verify the signature:
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 vpn free VerifySignature {
public static void main(String[] args) throws Exception free vpn {
String vpn free envelopedData = "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIAwggLQMIIC" +
vpn下载 免费vpn 免费vpn "OQIEQ479uzANBgkqhkiG9w0BAQUFADCBrjEmMCQGCSqGSIb3DQEJARYXcm9zZXR0YW5ldEBtZW5k" +
vpn free 免费vpn vpn下载 vpn free "ZWxzb24uZGUxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIEwZCZXJsaW4xDzANBgNVBAcTBkJlcmxpbjEi" +
vpn下载 "MCAGA1UEChMZbWVuZGVsc29uLWUtY29tbWVyY2UgR21iSDEiMCAGA1UECxMZbWVuZGVsc29uLWUt" +
free vpn 免费vpn下载 vpn下载 免费vpn "Y29tbWVyY2UgR21iSDENMAsGA1UEAxMEbWVuZDAeFw0wNTEyMDExMzQyMTlaFw0xOTA4MTAxMzQy" +
free 免费vpn vpn 免费vpn下载 "MTlaMIGuMSYwJAYJKoZIhvcNAQkBFhdyb3NldHRhbmV0QG1lbmRlbHNvbi5kZTELMAkGA1UEBhMC" +
vpn下载 免费vpn 免费vpn "REUxDzANBgNVBAgTBkJlcmxpbjEPMA0GA1UEBxMGQmVybGluMSIwIAYDVQQKExltZW5kZWxzb24t" 免费vpn +
vpn下载 vpn free "ZS1jb21tZXJjZSBHbWJIMSIwIAYDVQQLExltZW5kZWxzb24tZS1jb21tZXJjZSBHbWJIMQ0wCwYD" +
vpn free "VQQDEwRtZW5kMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+X1g6JvbdwJI6mQMNT41GcycH" +
"UbwCFWKJ4qHDaHffz3n4h+uQJJoQvc8yLTCfnl109GB0yL2Y5YQtTohOS9IwyyMWBhh77WJtCN8r" +
免费vpn下载 免费vpn 免费vpn "dOfD2DW17877te+NlpugRvg6eOH6np9Vn3RZODVxxTyyJ8pI8VMnn13YeyMMw7VVaEO5hQIDAQAB" +
免费vpn下载 免费vpn "MA0GCSqGSIb3DQEBBQUAA4GBALwOIc/rWMAANdEh/GgO/DSkVMwxM5UBr3TkYbLU/5jg0Lwj3Y++" +
vpn下载 vpn下载 "KhumYSrxnYewSLqK+JXA4Os9NJ+b3eZRZnnYQ9eKeUZgdE/QP9XE04y8WL6ZHLB4sDnmsgVaTU+p" +
免费vpn "0lFyH0Te9NyPBG0J88109CXKdXCTSN5gq0S1CfYn0staAAAxggG9MIIBuQIBATCBtzCBrjEmMCQG" +
免费vpn下载 "CSqGSIb3DQEJARYXcm9zZXR0YW5ldEBtZW5kZWxzb24uZGUxCzAJBgNVBAYTAkRFMQ8wDQYDVQQI" +
vpn下载 免费vpn vpn free free vpn free vpn 免费vpn "EwZCZXJsaW4xDzANBgNVBAcTBkJlcmxpbjEiMCAGA1UEChMZbWVuZGVsc29uLWUtY29tbWVyY2Ug" +
vpn free vpn free "R21iSDEiMCAGA1UECxMZbWVuZGVsc29uLWUtY29tbWVyY2UgR21iSDENMAsGA1UEAxMEbWVuZAIE" +
免费vpn vpn free "Q479uzAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUx" +
vpn下载 vpn free 免费vpn下载 vpn free 免费vpn "DxcNMTMwNTIxMDE1MDUzWjAjBgkqhkiG9w0BCQQxFgQU8mE6gw6iudxLUc9379lWK0lUSWcwDQYJ" +
vpn free 免费vpn "KoZIhvcNAQEBBQAEgYB5mVhqJu1iX9nUqfqk7hTYJb1lR/hQiCaxruEuInkuVTglYuyzivZjAR54" +
vpn free vpn下载 vpn下载 free vpn 免费vpn 免费vpn下载 "zx7Cfm5lkcRyyxQ35ztqoq/V5JzBa+dYkisKcHGptJX3CbmmDIa1s65mEye4eLS4MTBvXCNCUTb9" +
free vpn 免费vpn下载 免费vpn下载 "STYSWvr4VPenN80mbpqSS6JpVxjM0gF3QTAhHwAAAAAAAA==";
vpn下载 vpn下载 Security.addProvider(new vpn下载 BouncyCastleProvider());
free vpn CMSSignedData cms vpn下载 = new CMSSignedData(Base64.decode(envelopedData.getBytes()));
vpn free Store store = cms.getCertificates();
SignerInformationStore signers = cms.getSignerInfos();
Collection c = signers.getSigners();
免费vpn Iterator it = c.iterator();
vpn下载 while (it.hasNext()) {
vpn下载 free 免费vpn vpn SignerInformation signer = (SignerInformation) it.next();
免费vpn下载 Collection certCollection = store.getMatches(signer.getSID());
免费vpn下载 免费vpn vpn下载 vpn free Iterator certIt = certCollection.iterator();
vpn下载 免费vpn X509CertificateHolder certHolder = (X509CertificateHolder) certIt.next();
免费vpn下载 vpn下载 X509Certificate 免费vpn cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder);
vpn下载 free vpn if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert))) {
vpn下载 免费vpn 免费vpn下载 System.out.println("verified");
vpn下载 免费vpn 免费vpn }
免费vpn }
}
}
由于以下 Exception,在 signer.verify(..) 之前一切正常:
Everything works free vpn fine until signer.verify(..) due to the following Exception:
Exception in thread vpn 免费vpn free "main" org.bouncycastle.cms.CMSSignerDigestMismatchException: message-digest attribute free vpn value does not match calculated value
免费vpn下载 at org.bouncycastle.cms.SignerInformation.doVerify(Unknown Source)
vpn free at org.bouncycastle.cms.SignerInformation.verify(Unknown Source)
at my.package.VerifySignature.main(VerifySignature.java:64)
有人可以告诉我可能发生的事情吗?
Can someone please give me a hint of what could be happening?
PS.如果有人想在 code 上进行测试,您将需要我用来复制它的测试 certificate 文件,只需从此处 download 即可:
PS. If someone wants to test above code you will need the test certificate file that I am using to replicate this, just download it from here: vpn下载
https://www.dropbox.com/s/zs4jo1a86v8qamw/证书.p12?dl=0
推荐答案
gen.generate(msg, false)
表示签名数据不封装在签名中.如果您想创建一个分离的签名,这很好,但这确实意味着当您去验证 SignedData 时,您必须使用获取数据副本的 CMSSignedData 构造函数 - 在这种情况下,代码使用单个必须假设签名数据已封装的参数构造函数(因此在这种情况下将为空),结果是验证尝试失败.
means the signed data is not encapsulated in 免费vpn下载 the signature. This is fine if you want to create a detached signature, but it does mean that when 免费vpn 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 免费vpn下载 argument vpn free constructor 免费vpn下载 which 免费vpn 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 签名和验证签名的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!


大气响应式网络建站服务公司织梦模板
高端大气html5设计公司网站源码
织梦dede网页模板下载素材销售下载站平台(带会员中心带筛选)
财税代理公司注册代理记账网站织梦模板(带手机端)
成人高考自考在职研究生教育机构网站源码(带手机端)
高端HTML5响应式企业集团通用类免费vpn织梦模板(自适应手机端)