我正在使用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进行签名和验证签名的正确方法相关推荐

  1. iOS使用Security.framework进行RSA 加密解密签名和验证签名

    iOS 上 Security.framework为我们提供了安全方面相关的api: Security框架提供的RSA在iOS上使用的一些小结 支持的RSA keySize 大小有:512,768,10 ...

  2. AVB之镜像的签名及验证签名详解

    文章目录 1.签名流程 1.1 镜像的签名 1.2 镜像的内容 2.验证镜像的hash和signature签名 2.1 计算hash 2.2 验证签名 1.签名流程 我们以一下空的dtbo.img镜像 ...

  3. 以太坊签名,验证签名, EIP712domain Permit授权并转账

    文章目录 一.Dapp 验签登录 web3.eth.accounts.recover(signtxt,sig) 具体实现过程 golang的实现 二.token EIP712Domain Domain ...

  4. 使用node加密解密数据,创建Hash/HMAC,并生成签名与验证签名

    1.数据加密与解密 主要使用了node的crypto模块的Cipher与Decipher类来加密解密,加密与解密的方法主要有以下几种: 1.1 使用Cipher与Decipher对象作为流来加密解密 ...

  5. java 属性签名_java – 使用BouncyCastle将签名/身份验证的属性添加到CMS签名

    首先,您似乎使用了最新版本的Bouncy Castle中不推荐使用的构造.要添加经过身份验证/签名的 attributes,您必须将它们打包成 AttributeTable签名属性添加到签名者,如下所 ...

  6. java版本微信jssdk、微信验证签名demo(Servlet)

    开发背景 最近在学习java,所以从网上看了一些别人的代码,再加入了自己的一些理解,主要是担心之后会忘记,所以写下一篇东西记录一下思路. 一. 获取acess_token以及jsapiTicket 新 ...

  7. java数字签名(签名生成,用证书验证签名)

    部分签名原理 http://blog.csdn.net/lijiecong/archive/2010/12/24/6096289.aspx (转载序:网上找的好文章,一篇就把我找了几天的所有东西都概括 ...

  8. java验证签名_简单API接口签名验证

    前言 后端在写对外的API接口时,一般会对参数进行签名来保证接口的安全性,在设计签名算法的时候,主要考虑的是这几个问题: 1. 请求的来源是否合法 2. 请求参数是否被篡改 3. 请求的唯一性 我们的 ...

  9. java 支付宝回调校验签名_支付宝异步回调验证签名

    今天做支付宝接口回调这块,不得不说,弄的我焦头烂额,翻了很多陈年旧帖,试了无数种解决坑的方案,在我成功解决的一瞬间,觉得非常有必要记录一下这些坑. 签名验证错误的检查顺序(这里是基于使用官方给的dem ...

最新文章

  1. FreeRTOS 任务优先级分配方案
  2. 基于gulp的前端脚手架(二)
  3. java grizzly_Grizzly简介
  4. 序1--年轻正当时(特权)
  5. 从零搭建分布式文件系统MinIO比FastDFS要更合适
  6. 15年大厂经历!大佬总结:0基础如何学习Python?
  7. 解决ArcGIS安装之后出现的Windows installer configures问题
  8. 如何检查Java中是否存在文件
  9. 译DevExpress v16.1更新说明(WinForms篇)
  10. SpringMVC:过滤器和拦截器的区别和实现原理
  11. 作业帮冯雪胡不归问题_【凭谁唤君胡不归作文】作业帮
  12. 区块链银行应用探索(Hyperledger fabric)
  13. win2008r2用户账户控制什么意思_养老保险统筹账户是什么意思?有什么用?
  14. 巨头再度加码区块链,蚂蚁金服发布区块链合作伙伴计划
  15. 无法将maven 编译部署src/main/java下的资源文件
  16. 树莓派UFW防火墙简单设置
  17. 专业工作站版、企业版、企业LTSC版、Servers版哪个更稳定更适合应对灾难
  18. 小技巧:absolute 元素的宽度问题
  19. kali linux 2018.1版下安装w3af 【超详细】
  20. centos mysql ssh连接,使用SSH隧道连接MYSQL

热门文章

  1. DDD理论学习系列(13)-- 模块
  2. Dapper源码学习和源码修改
  3. 第三篇 Entity Framework Plus 之 Query Cache
  4. python异或运算怎么算_小强学Python+OpenCV之-1.4.4掩膜mask及位运算(与、或、非、异或)...
  5. [转]2020年排名前20的基于SpringBoot搭建的开源项目,帮你快速进行项目搭建!
  6. 【ArcGIS遇上Python】Python使用栅格数据
  7. C语言试题七十二之请编写函数判断三角形的类型,并输出其面积和类型。
  8. linux之nm命令
  9. Android之如何解决刚下载的Android studio(包括上面的菜单栏)乱码问题
  10. Android之UI线程与子线程交互设计的5种方法