java bouncycastle_java – 使用bouncycastle进行签名和验证签名的正确方法
我正在使用bcmail-jdk16-1.46.jar和bcprov-jdk16-1.46.jar(Bouncycastle库)来签名一个字符串,然后验证签名。
这是我的代码来签字符串:
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输出将在此过程中用于通过以下方式验证签名:
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");
}
}
}
}
一切都很好,直到signer.verify(..)由于以下异常:
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)
我真的不知道我做错了什么有人可以给我一个发生什么的提示吗?
PS。如果有人想测试上面的代码,你将需要我使用的测试证书文件来复制所有这些,只需从这里下载/保存:
提前致谢。
java bouncycastle_java – 使用bouncycastle进行签名和验证签名的正确方法相关推荐
- iOS使用Security.framework进行RSA 加密解密签名和验证签名
iOS 上 Security.framework为我们提供了安全方面相关的api: Security框架提供的RSA在iOS上使用的一些小结 支持的RSA keySize 大小有:512,768,10 ...
- AVB之镜像的签名及验证签名详解
文章目录 1.签名流程 1.1 镜像的签名 1.2 镜像的内容 2.验证镜像的hash和signature签名 2.1 计算hash 2.2 验证签名 1.签名流程 我们以一下空的dtbo.img镜像 ...
- 以太坊签名,验证签名, EIP712domain Permit授权并转账
文章目录 一.Dapp 验签登录 web3.eth.accounts.recover(signtxt,sig) 具体实现过程 golang的实现 二.token EIP712Domain Domain ...
- 使用node加密解密数据,创建Hash/HMAC,并生成签名与验证签名
1.数据加密与解密 主要使用了node的crypto模块的Cipher与Decipher类来加密解密,加密与解密的方法主要有以下几种: 1.1 使用Cipher与Decipher对象作为流来加密解密 ...
- java 属性签名_java – 使用BouncyCastle将签名/身份验证的属性添加到CMS签名
首先,您似乎使用了最新版本的Bouncy Castle中不推荐使用的构造.要添加经过身份验证/签名的 attributes,您必须将它们打包成 AttributeTable签名属性添加到签名者,如下所 ...
- java版本微信jssdk、微信验证签名demo(Servlet)
开发背景 最近在学习java,所以从网上看了一些别人的代码,再加入了自己的一些理解,主要是担心之后会忘记,所以写下一篇东西记录一下思路. 一. 获取acess_token以及jsapiTicket 新 ...
- java数字签名(签名生成,用证书验证签名)
部分签名原理 http://blog.csdn.net/lijiecong/archive/2010/12/24/6096289.aspx (转载序:网上找的好文章,一篇就把我找了几天的所有东西都概括 ...
- java验证签名_简单API接口签名验证
前言 后端在写对外的API接口时,一般会对参数进行签名来保证接口的安全性,在设计签名算法的时候,主要考虑的是这几个问题: 1. 请求的来源是否合法 2. 请求参数是否被篡改 3. 请求的唯一性 我们的 ...
- java 支付宝回调校验签名_支付宝异步回调验证签名
今天做支付宝接口回调这块,不得不说,弄的我焦头烂额,翻了很多陈年旧帖,试了无数种解决坑的方案,在我成功解决的一瞬间,觉得非常有必要记录一下这些坑. 签名验证错误的检查顺序(这里是基于使用官方给的dem ...
最新文章
- FreeRTOS 任务优先级分配方案
- 基于gulp的前端脚手架(二)
- java grizzly_Grizzly简介
- 序1--年轻正当时(特权)
- 从零搭建分布式文件系统MinIO比FastDFS要更合适
- 15年大厂经历!大佬总结:0基础如何学习Python?
- 解决ArcGIS安装之后出现的Windows installer configures问题
- 如何检查Java中是否存在文件
- 译DevExpress v16.1更新说明(WinForms篇)
- SpringMVC:过滤器和拦截器的区别和实现原理
- 作业帮冯雪胡不归问题_【凭谁唤君胡不归作文】作业帮
- 区块链银行应用探索(Hyperledger fabric)
- win2008r2用户账户控制什么意思_养老保险统筹账户是什么意思?有什么用?
- 巨头再度加码区块链,蚂蚁金服发布区块链合作伙伴计划
- 无法将maven 编译部署src/main/java下的资源文件
- 树莓派UFW防火墙简单设置
- 专业工作站版、企业版、企业LTSC版、Servers版哪个更稳定更适合应对灾难
- 小技巧:absolute 元素的宽度问题
- kali linux 2018.1版下安装w3af 【超详细】
- centos mysql ssh连接,使用SSH隧道连接MYSQL
热门文章
- DDD理论学习系列(13)-- 模块
- Dapper源码学习和源码修改
- 第三篇 Entity Framework Plus 之 Query Cache
- python异或运算怎么算_小强学Python+OpenCV之-1.4.4掩膜mask及位运算(与、或、非、异或)...
- [转]2020年排名前20的基于SpringBoot搭建的开源项目,帮你快速进行项目搭建!
- 【ArcGIS遇上Python】Python使用栅格数据
- C语言试题七十二之请编写函数判断三角形的类型,并输出其面积和类型。
- linux之nm命令
- Android之如何解决刚下载的Android studio(包括上面的菜单栏)乱码问题
- Android之UI线程与子线程交互设计的5种方法