p1和p7签名的区别

前言:
P1签名:即裸签名,签名值中只有签名信息.
p7签名:即,签名中可以带有其他的附加信息,例如签名证书信息,签名原文信息,时间戳信息等.
所以要注意,不要p7的签名,用p1的方式来验签,这样是不对的.是错误的.

数字签名中,包含了两个过程:
1.对要签名的信息,用指定的hash算法,获取信息的hash值.
2.用私钥,对hash值进行加密,输出加密串(也就是签名值).
以上方式也就是裸签名,PKCS#1

验证签名:
1.对要签名的信息(也就是签名原文),用指定的hash算法,获取信息的hash值.
2.用公钥信息,解密签名值,从中获取加密的hash串,和上面获取的hash值进行对比,一致则认为验签通过,不一致则不通过.

需要注意,如果调用远程签名(比如电子签名),因为根据要签名的数据格式的不同,所以我们本地验签的时候,也要根据不同的签名方式,来进行验证(也就说,他们那边签名的时候,真正用来签名的字节数组是怎么来的)

目前常见的几种方式:(P1签名验签)

contentType==CT_MESSAGE时,为待签名的消息;
contentType==CT_BASE64_DATA时,为待签名的base64编码数据;
contentType==CT_HASH时为待签名的HASH;
contentType==CT_FILE_URL时为待签名文件地址URL
contentType== CT_STORAGE时为待签名内容存储编号

CT_HASH:告诉签名方,我这个是对签名原文hash过了的hash串,你们直接对这个值进行加密即可,不需要再hash了.
所以这种方式,我们本地验签的时候,要将原文放入进行验签,而不是hash过后的hash值(因为验签的时候,它又会hash一次)

  /*** 测试hash方式的签名验签* @throws Exception */@Testpublic void testSignWithHash() {try {CertificateFactory cf = CertificateFactory.getInstance("X.509");  Certificate usercert = cf.generateCertificate(new FileInputStream(USER_CERT)); PublicKey publicKey = usercert.getPublicKey();//读取pfx证书上的秘钥对信息BouncyCastleProvider provider = new BouncyCastleProvider();Signature signature = Signature.getInstance("SHA1withRSA"); MessageDigest digest = MessageDigest.getInstance("SHA-1", provider);List<UserInfo> userInfoList = userInfoService.findAll();UserInfo userInfo = userInfoList.get(0);Map<String, Object> puserCert = new HashMap<>();puserCert.put("userInfo", userInfo);List<UserCert> userCertList = userCertService.getListByParam(puserCert);UserCert userCert = userCertList.get(0);YuanZi_P1SignRequest yuanZiP1SignRequest = new YuanZi_P1SignRequest();yuanZiP1SignRequest.setAlias(userInfo.getAlias());yuanZiP1SignRequest.setHashAlg("SHA1");yuanZiP1SignRequest.setContentType("CT_HASH");String content = "我是签名原文";byte[] dataToSign = digest.digest(content.getBytes(Charset.forName("UTF-8")));System.out.println("dataToSign:"+Base64.encodeBytes(dataToSign));yuanZiP1SignRequest.setContent(Base64.encodeBytes(dataToSign));YuanZi_P1SignResponse yuanZiP1SignResponse = yuanZiService.signP1(yuanZiP1SignRequest);System.out.println("原子服务返回的签名值:"+yuanZiP1SignResponse.getSignedData());byte[] dataHadSignature = Base64.decode(yuanZiP1SignResponse.getSignedData());YuanZi_VerifyP1SignRequest yuanZiVerifyP1SignRequest = new YuanZi_VerifyP1SignRequest();yuanZiVerifyP1SignRequest.setSignedData(yuanZiP1SignResponse.getSignedData());yuanZiVerifyP1SignRequest.setContentType("CT_HASH");yuanZiVerifyP1SignRequest.setContent(Base64.encodeBytes(dataToSign));yuanZiVerifyP1SignRequest.setHashAlg("SHA1");yuanZiVerifyP1SignRequest.setCert(userCert.getCertBuf().getCertsignBuf());YuanZi_VerifyP1SignResponse yuanZiVerifyP1SignResponse = yuanZiService.verifyP1Sign(yuanZiVerifyP1SignRequest);System.out.println(yuanZiVerifyP1SignResponse.getCode());//本地验签boolean verify=false;  signature.initVerify(usercert);  //使用公钥初始化签名对象,用于验证签名  signature.update(content.getBytes(Charset.forName("UTF-8")));verify= signature.verify(dataHadSignature); //得到验证结果  System.out.println("本地的验签结果:"+verify);} catch (Exception e) {e.printStackTrace();// TODO: handle exception}}

CT_MESSAGE:即,告诉签名方,我发过去的内容,就是签名的原文.一般来说,因为签名值都是字节数组,所以签名方会根据约定的编码方式,对这个签名原文按规定的编码方式,取它的字节数组之后,进行签名

我们本地验签的时候,也要对原文做同样的操作

 /*** 测试原子服务P1方式的签名和验签通过* @throws Exception */@Testpublic void testSign_P1_CT_MESSAGE() {try {CertificateFactory cf = CertificateFactory.getInstance("X.509");  Certificate usercert = cf.generateCertificate(new FileInputStream(USER_CERT)); PublicKey publicKey = usercert.getPublicKey();//读取pfx证书上的秘钥对信息BouncyCastleProvider provider = new BouncyCastleProvider();Signature signature = Signature.getInstance("SHA1withRSA"); MessageDigest digest = MessageDigest.getInstance("SHA-1", provider);List<UserInfo> userInfoList = userInfoService.findAll();UserInfo userInfo = userInfoList.get(0);Map<String, Object> puserCert = new HashMap<>();puserCert.put("userInfo", userInfo);List<UserCert> userCertList = userCertService.getListByParam(puserCert);UserCert userCert = userCertList.get(0);YuanZi_P1SignRequest yuanZiP1SignRequest = new YuanZi_P1SignRequest();yuanZiP1SignRequest.setAlias(userInfo.getAlias());yuanZiP1SignRequest.setHashAlg("SHA1");yuanZiP1SignRequest.setContentType("CT_MESSAGE");String content = "我是签名原文";yuanZiP1SignRequest.setContent(content);YuanZi_P1SignResponse yuanZiP1SignResponse = yuanZiService.signP1(yuanZiP1SignRequest);System.out.println("原子服务返回的签名值:"+yuanZiP1SignResponse.getSignedData());byte[] dataHadSignature = Base64.decode(yuanZiP1SignResponse.getSignedData());YuanZi_VerifyP1SignRequest yuanZiVerifyP1SignRequest = new YuanZi_VerifyP1SignRequest();yuanZiVerifyP1SignRequest.setSignedData(yuanZiP1SignResponse.getSignedData());yuanZiVerifyP1SignRequest.setContentType("CT_MESSAGE");yuanZiVerifyP1SignRequest.setContent(content);yuanZiVerifyP1SignRequest.setHashAlg("SHA1");yuanZiVerifyP1SignRequest.setCert(userCert.getCertBuf().getCertsignBuf());YuanZi_VerifyP1SignResponse yuanZiVerifyP1SignResponse = yuanZiService.verifyP1Sign(yuanZiVerifyP1SignRequest);System.out.println(yuanZiVerifyP1SignResponse.getCode());//本地验签boolean verify=false;  signature.initVerify(usercert);  //使用公钥初始化签名对象,用于验证签名  signature.update(content.getBytes(Charset.forName("UTF-8")));verify= signature.verify(dataHadSignature); //得到验证结果  System.out.println("本地的验签结果:"+verify);} catch (Exception e) {e.printStackTrace();// TODO: handle exception}}

CT_BASE64_DATA:因为有时候,我们要签名的原文,它就是一个byte[],但是为了方便传输,一般签名方都要求接受的是一个字符串.所以就有了这种签名方式.即:我们需要对签名原文的byte[]做base64编码,签名方收到之后,再做解码,并且把解码后的byte[]进行签名.
所以我们本身验签的时候,只要传入byte[]就行.
第三方返回的签名值,一般也是签名值byte[]做base64编码后的字符串,所以我们要做base64解码,才能获取到签名值byte[].
 

/*** 测试原子服务P1方式的CT_BASE64_DATA签名和验签通过* @throws Exception * * 注意多种签名方式,你传给它要签名的数据,和它最后执行签名的时候,真正要签的那个原文可能跟你传的不是同一个(比如需要做String 转为byte,base64编码要解码)*/@Testpublic void testSign_P1_CT_BASE64_DATA() {try {CertificateFactory cf = CertificateFactory.getInstance("X.509");  Certificate usercert = cf.generateCertificate(new FileInputStream(USER_CERT)); PublicKey publicKey = usercert.getPublicKey();//读取pfx证书上的秘钥对信息BouncyCastleProvider provider = new BouncyCastleProvider();Signature signature = Signature.getInstance("SHA1withRSA"); MessageDigest digest = MessageDigest.getInstance("SHA-1", provider);List<UserInfo> userInfoList = userInfoService.findAll();UserInfo userInfo = userInfoList.get(0);Map<String, Object> puserCert = new HashMap<>();puserCert.put("userInfo", userInfo);List<UserCert> userCertList = userCertService.getListByParam(puserCert);UserCert userCert = userCertList.get(0);YuanZi_P1SignRequest yuanZiP1SignRequest = new YuanZi_P1SignRequest();yuanZiP1SignRequest.setAlias(userInfo.getAlias());yuanZiP1SignRequest.setHashAlg("SHA1");yuanZiP1SignRequest.setContentType("CT_BASE64_DATA");byte[] dataToSign = new byte[10];String base64ToSign = Base64.encodeBytes(dataToSign);yuanZiP1SignRequest.setContent(base64ToSign);YuanZi_P1SignResponse yuanZiP1SignResponse = yuanZiService.signP1(yuanZiP1SignRequest);System.out.println("原子服务返回的签名状态:"+yuanZiP1SignResponse.getCode());System.out.println("原子服务返回的签名值:"+yuanZiP1SignResponse.getSignedData());//签名后的byte[] dataHadSignature = Base64.decode(yuanZiP1SignResponse.getSignedData());YuanZi_VerifyP1SignRequest yuanZiVerifyP1SignRequest = new YuanZi_VerifyP1SignRequest();yuanZiVerifyP1SignRequest.setSignedData(yuanZiP1SignResponse.getSignedData());yuanZiVerifyP1SignRequest.setContentType("CT_BASE64_DATA");yuanZiVerifyP1SignRequest.setContent(base64ToSign);yuanZiVerifyP1SignRequest.setHashAlg("SHA1");yuanZiVerifyP1SignRequest.setCert(userCert.getCertBuf().getCertsignBuf());YuanZi_VerifyP1SignResponse yuanZiVerifyP1SignResponse = yuanZiService.verifyP1Sign(yuanZiVerifyP1SignRequest);System.out.println(yuanZiVerifyP1SignResponse.getCode());System.out.println(yuanZiVerifyP1SignResponse.getMessage());//本地验签boolean verify=false;  signature.initVerify(publicKey);  //使用公钥初始化签名对象,用于验证签名  //原子signature.update(dataToSign);verify= signature.verify(dataHadSignature); //得到验证结果  System.out.println("本地的验签结果:"+verify);} catch (Exception e) {e.printStackTrace();// TODO: handle exception}}

P7签名:
P7签名其实也就是P1签名的基础上,附加一些其他的信息(因为P1是裸签名,只有加密串,除了本人自己,根本不知道签名证书,公钥,签名算法,签名用的hash算法,时间戳,签名原文等等信息是什么,不便于验证签名,所以就需要有P7签名作为补充,其实也就是在P1之后,在加密串的基础上,附加这些信息上去)

补充:
因为P7签名值包含签名证书,原文等信息,所以发送到服务器验签的时候,只需要把签名值发给服务器即可,而p1,是裸签名,发送到服务器验证的时候,需要签名证书,签名值,和原文三个参数才能验证

所以我们在itextpdf的源码上能看到,其实它做签名的时候,也就是先构建出一个要签名的字符串,然后丢给某个私钥进行签名,获得签名值,它再对这个签名值附加:证书链,时间戳等等信息,然后构建出一个P7签名,然后放入PDF文件中.

PKCS#1:定义RSA公开密钥算法加密和签名机制,主要用于组织PKCS#7中所描述的数字签名和数字信封[22]。
PKCS#7:定义一种通用的消息语法,包括数字签名和加密等用于增强的加密机制,PKCS#7与PEM兼容,所以不需其他密码操作,就可以将加密的消息转换成PEM消息[26]。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/495722.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用 Python 和 werobot 框架开发公众号

From&#xff1a;用 Python 和 werobot 框架开发公众号&#xff1a;https://www.jianshu.com/p/a517746a900f WeRoBot 官方文档 &#xff1a;https://werobot.readthedocs.io/zh_CN/latest/ Github &#xff1a;https://github.com/offu/WeRoBot Python — WeRobot&#xff0…

专家:智能芯片国际竞争愈发激烈,应尽快制定国家标准

来源&#xff1a; 科技日报摘要&#xff1a;近日&#xff0c;十三届全国政协第一次双周协商座谈会在京召开。会议聚焦的话题是人工智能的发展与对策。夯实基础&#xff0c;提升原始创新能力中科院计算所智能处理器中心主任陈云霁做的就是智能芯片&#xff0c;作为智能芯片公司寒…

easyExcel 使用指南详解

来源&#xff1a;easyExcel 使用指南详解 - 知乎 easyExcel简介 Java领域解析、生成Excel比较有名的框架有Apache poi、jxl等。但他们都存在一个严重的问题就是非常的耗内存。如果你的系统并发量不大的话可能还行&#xff0c;但是一旦并发上来后一定会OOM或者JVM频繁的full g…

(转)Web Services使用多态(XmlInclude) ,支持自定义类型

Web Services使用多态(XmlInclude) 在Web Services方法中&#xff0c;往往使用的都是一个具体类型的参数&#xff0c;这个参数一般就是一个数据对象。ASP.NET Web Services通过声明XmlIncludeAttribute可以实现Web Services方法中运用多态。 XmlIncludeAttribute允许XmlSeriali…

EasyExcel快速上手~读取

对象 // 如果没有特殊说明&#xff0c;下面的案例将默认使用这个实体类 public class DemoData {private String string;private Date date;private Double doubleData;// getting setting }监听器 // 如果没有特殊说明&#xff0c;下面的案例将默认使用这个监听器 public cl…

激光破解太空通信难题

来源&#xff1a;新浪科技摘要&#xff1a;虽然目前而言无线电天线仍然是太空通信的支柱&#xff0c;但目前未来发展方向是激光通讯系统。在太空中&#xff0c;没有人会听到你的尖叫——因为声音不会在真空中传播&#xff0c;而且你需要某种类型的无线电波中继携载这些信息&…

Docker 原理、学习教程

Docker 官网 &#xff1a;https://www.docker.com/ Docker Hub&#xff1a;https://registry.hub.docker.com/search?qkali Docker 容器超详细讲解&#xff1a;https://www.linuxidc.com/Linux/2018-08/153712.htm Docker Compose&#xff1a;https://www.runoob.com/docker…

System.Runtime.InteropServices.Automation

提供使基于 Silverlight 的应用程序可以与自动化 API 进行交互操作的类。 类&#xff1a; 1.AutomationEvent:  表示一个自动化事件 2.AutomationEventArgs:  为AutomationEvent.EventRaised事件提供数据 3. AutomationFactory :  提供对已注册的自动化服务器的访问转载于…

从自动驾驶到基因编辑,这15项发明专利改变了世界

来源&#xff1a;资本实验室近期&#xff0c;中兴通讯受美国制裁的事件戳中了国人心中的“痛”&#xff0c;也对我们长期受制于人的芯片核心技术与产业敲响了警钟。我们近乎被动地发现&#xff0c;在科技创新&#xff0c;尤其是技术驱动型创新方面&#xff0c;我们的差距到底有…

org.dom4j.DocumentFactory cannot be cast to org.dom4j.DocumentFactory

引入cryptofront-2.1.6.jar后dom4j执行异常 解决方案&#xff0c;强制在cryptofront-2.1.6.jar加载前&#xff0c;加载dom4j dom4j引入不完整

【原】StreamInsight 浅入浅出(四)—— 例子

对于StreamInsight这种不是很线性的架构&#xff0c;最好还是直接拿出来一个例子&#xff0c;简单但完整的把流程走过一遍&#xff0c;更能看清所谓“流”、“事件”、“适配器”之类到底是什么东西&#xff0c;有什么关系。 官方例子下载地址&#xff1a;http://go.microsoft.…

Cheat Engine 教程( 1 - 9 通关 )

工具包&#xff1a;https://down.52pojie.cn/Tools/Debuggers/ Cheat Engine 官网&#xff1a;https://www.cheatengine.org/ ce 修改器绿色版(cheat engine) v7.4 官方最新版&#xff1a;http://www.downcc.com/soft/21673.html 这个教程全部是来自 Cheat Engine 软件的中的…

人工智能元老痛批IBM:沃森是个骗局,这根本不是认知

作者 Roger Schank李林 编译整理量子位 出品 | 公众号 QbitAI一篇质疑IBM的旧文今天在HackerNews上火了起来&#xff0c;虽已时隔两年&#xff0c;这篇文章还是引起了网友们的强烈共鸣。文章作者Roger Schank是AI领域元老人物&#xff0c;AAAI Fellow&#xff0c;曾任耶鲁大学人…

判断字符串中是否包含中文

判断字符串中是否包含中文 selectcasewheny我like%[啊-座]%then包含中文 else不包含中文 end转载于:https://www.cnblogs.com/stublue/archive/2010/11/05/1869916.html

OllyDBG完美教程(超强入门级)

OllyDBG 视频教程&#xff1a;https://www.bilibili.com/video/av6889190 动态调试工具之OllyDbg(OD)教程&#xff1a;https://www.bilibili.com/video/av70600053 使用 OllyDbg 从零开始 Cracking.chm ( 58章 )&#xff1a;https://pan.baidu.com/s/18iXvF5I_No4-a1DK3jKrbg …

12种Bean转换

来源&#xff1a;再见 BeanUtils&#xff01;性能真拉跨&#xff01; 一、前言 二、性能测试对比 三、12种转换案例 1. get\set 2. json2Json 3. Apache copyProperties 4. Spring copyProperties 5. Bean Mapping 6. Bean Mapping ASM 7. BeanCopier 8. Orika 9. Do…

上海人工智能再出重磅!寒武纪科技发布新一代云端AI芯片,联想、曙光、科大讯飞发布相关应用...

来源&#xff1a;文汇网 作者&#xff1a;许琦敏、郭超豪峰值功耗不超过110瓦&#xff0c;等效理论峰值速度可达每秒166.4万亿次定点运算。寒武纪科技在上海发布了中国第一款云端智能芯片——Cambricon MLU100芯片和板卡产品、寒武纪1M终端智能处理器IP产品。联想、曙光和科大…

OD 快捷键使用大全。非常详细( 游戏逆向分析必看 )+ OD 断点 使用大全

From&#xff1a;https://www.cnblogs.com/YiShen/p/9742872.html OllyDBG 快捷键 OllyDbg 窗口通用快捷键 快捷键    功能      Ctrl F2重启程序&#xff0c;即重新启动被调试程序&#xff08; 重新载入程序 &#xff09;。如果当前没有调试的程序&#xff0c;Oll…

电子发票中数字签名的提取解析

前言 随着电子信息技术的发展与成熟&#xff0c;加上国家的大力推广&#xff0c;电子发票已经开始慢慢取代纸质发票。相比传统的纸质发票&#xff0c;电子发票除了绿色环保&#xff0c;节约成本之外&#xff0c;更重要的是电子发票采取电子签章实现发票签名、电子盖章&#xff…

主流流媒体软件pplive和ppstream的分析

现有P2P流媒体软件开发新的流媒体系统&#xff0c;充分了解现有的流媒体软件的优劣得失是必不可少的。主流的软件pplive和ppstream就是分析的对象。以下分析全部基于Sockmon5的数据包拦截。手上资源有限&#xff0c;对协议的分析不很充分。 一、pplive&#xff1a;这款…