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

前言
随着电子信息技术的发展与成熟,加上国家的大力推广,电子发票已经开始慢慢取代纸质发票。相比传统的纸质发票,电子发票除了绿色环保,节约成本之外,更重要的是电子发票采取电子签章实现发票签名、电子盖章,具有唯一性、不可抵赖性、防篡改等优点,而且更加容易税务管理。那么,我们平常拿到一张电子发票,应该如何验证它的真伪呢?如何保证它是合法且没有被别人篡改呢?这就需要对电子发票的原理有所了解了。下文将慢慢分析电子发票文件的内部结构,并尝试对电子发票中数字证书及签名进行解析。

电子发票的结构
我们收到的电子发票文件后缀名都是.ofd,它的载体就是OFD版式文件,OFD文件我们可以简单认为它就是我们国家自主研发与定义的文件格式,类似于PDF,我们通过winzip或者7zip等解压工具打开,就可以看到它的内部结构。
在这里插入图片描述

从图中可以看到,电子发票主要分为两个体系,一个是内容体系,主要描述发票各个要素承载的信息以及样式;另外一个是签名体系,用于校验发票的正确性。
这里和验证相关的的文件主要是Signature.xml(签名/签章描述文件)、Seal.esl(电子印章文件)和SignedValue.dat(签名值文件)。

电子发票的验证步骤
我们拿到这三个文件需要怎么做呢?最权威的国标文件给出了验证的具体步骤,如图所示:
在这里插入图片描述

 在这里插入图片描述

 在这里插入图片描述

好家伙,光验证步骤就有a~h步,其中第d步是验证电子印章的有效性,而这里又是涉及到多个步骤:  在这里插入图片描述

 

怎么理解这一堆复杂的步骤呢?电子签章和电子印章的区别是什么?
想象一下我们收到一张发票,应该怎样去验证它的真伪呢?

需要保证电子发票是开票者开具的,文件并没有被篡改过。
需要验证发票上的印章是真实有效的。
上面提到的第1点就是电子签章的验证,第2点就是电子印章的验证。两者缺一不可。
而无论是电子签章还是电子印章,核心又是对数字签名进行验证,因此,提取文件中的证书文件是关键。下面以电子印章(Seal.esl)为例,介绍一下如何解析里面的内容。

电子印章的文件组成
电子印章文件是一个二进制文件,通过文本工具是无法得知里面的内容。实际上,电子印章是以ASN.1格式来存储的。
ASN.1是什么东西呢?ASN.1是国际电信标准(ITU-T)定义的标准,用来结构化描述证书,ASN.1类似于JSON或者XML这样的数据结构。一般的证书都是通过ASN.1来定义的。
https://lapo.it/asn1js/ 是一个神奇的在线ASN.1解析网站,把Seal.esl丢上去,可以看到电子印章的内容基本都被解析出来了:
在这里插入图片描述

可以看到电子印章文件的大致结构,里面包含了电子印章的一些基础信息,例如印章信息、制章者、签名算法、签名值等。唯一有点遗憾的是无法通过结果得知各个元素的名称与作用,这是由于网站无法知道我们的数据结构是怎样定义的。我们还是要更加深入研究国标中对电子印章的数据结构定义。 

在这里插入图片描述

上图是电子印章中印章属性的结构定义,我们可以理解电子印章是在原有数字证书的基础上封装了一些信息,核心还是里面的数字证书Certificate(如下图红框所示),而这个证书与我们平时浏览器上信任的证书是同一个东西。 

在这里插入图片描述

通过Java编写程序,我们可以更加定制化地专门解析电子印章的内容,并且能提取出证书的内容,为后面的数字签名验证打下基础。

电子印章的解析

目前最主流的java解析ASN.1内容工具是:bcprov,使用方法也相当简单。 

<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.68</version>
</dependency>
@Slf4j
public class TestAsn1Parser {@Testpublic void testData() throws Exception{// 1. 读取电子印章(Seal.esl)ASN1InputStream bin = new ASN1InputStream(new ByteArrayInputStream(IOUtils.toByteArray(AsnParser.class.getResourceAsStream("Seal.esl"))));ASN1Primitive obj = bin.readObject();DLSequence app = (DLSequence) obj;// 2. 根据国标定义,找到证书二进制内容的位置DEROctetString cert = (DEROctetString) app.getObjectAt(1);ASN1InputStream bin2 = new ASN1InputStream(cert.getOctets());DLSequence seq = (DLSequence) bin2.readObject();// 3. 解析证书内容Certificate certificate = Certificate.getInstance(seq);TBSCertificate tbsCertificate = certificate.getTBSCertificate();// 示例:获取证书内数字签名的主要元素log.info("签名算法:{}", certificate.getSignatureAlgorithm().getAlgorithm());log.info("签名值:{}", certificate.getSignature());TBSCertificate tbsCertificate = certificate.getTBSCertificate();log.info("公钥:{}", tbsCertificate.getSubjectPublicKeyInfo().getPublicKeyData());}
}

在这里插入图片描述

例子中只对电子印章中的证书部分进行解析,实际应用中我们可以创建对应的实现来完全映射国标中的数据结构。
通过上面代码得到电子印章的数字签名信息,包括:

签名算法是1.2.156.10197.1.501(国标中对应的是国密算法:基于SM3的SM2签名)
签名值
公钥
有了上面的信息,接下来要做的事情就简单了,只需对该数字签名进行验证即可。

后记
上面介绍的仅仅是电子发票验证的一小部分,由于篇幅有限,除了要对数字签名验证以外,还需要验证证书的有效性,这里又涉及到证书链与CRL相关的验证。而电子印章验证通过后还需进行电子签章的验证。有时间的话将进一步补充介绍后面的步骤。
电子发票涉及相关的内容较多,包括了OFD、ASN.1和信息安全、密码学等相关知识,特别是相关国家标准较多,需要仔细参考研究其中的描述说明。上面的示例仅作参考,如有错漏,还请见谅。
By Ryan.ou

参考资料
[1] GB/T 33190-2016 电子文件存储与交换格式 版式文档
[2] GB/T 38540-2020 信息安全技术 安全电子签章密码 技术规范
[3] GB/T 20518 2018 信息安全技术 公钥基础设施 数字证书格式
[4] OFD开源读写组件
[5] ASN.1在线解析网站
[6] https://blog.csdn.net/weixin_42497593/article/details/112151171
————————————————
版权声明:本文为CSDN博主「软件开发随心记」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/vipshop_fin_dev/article/details/114240169

 

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

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

相关文章

无人车、超级高铁、智慧城市......这是一份来自未来的出行报告

来源&#xff1a;机器之能 作者&#xff1a;Charles McLellan 编译&#xff1a;王宇欣在新兴技术的驱动下&#xff0c;运输业即将迎来第二春。虽然个中细节还需打磨&#xff0c;但未来的运输系统必然会实现数据驱动、彼此相关联、高度自动化。有关技术与运输业未来的文章比比皆…

在 VC++ 中使用 内联汇编

From&#xff1a;https://blog.csdn.net/root19881111/article/details/8450266 VC内联汇编(MSDN相关内容完整翻译)&#xff1a;http://www.cppblog.com/xingkongyun/archive/2008/12/21/70003.html 调 call 和 偷功能 时&#xff0c;VC中内联汇编容易产生的错误&#xff1a;…

OFD 版式技术解析系列(一):开篇

在版式电子文件领域&#xff0c;大家比较熟悉的就是 PDF(Portable Document Format)格式&#xff0c;该格式由 Adobe 公司在 1992 年发布&#xff0c;迄今已经有 28 个年头&#xff0c;2008 年 7 月 1 日&#xff0c;IS 组织正式发布 PDF 的国际标准&#xff0c;PDF 成为了独立…

无人驾驶急需解决:规划控制和传感器价格高两大问题

来源&#xff1a;AI科技大本营 作者 &#xff1a;Mavis2017 年百度 AI 开发者大会上&#xff0c;现场视频连线了正乘坐无人驾驶汽车行驶在五环上朝会场赶来的李彦宏&#xff0c;他坐在副驾驶上解说&#xff0c;身边司机的双手并没有触碰方向盘&#xff0c;也正是因为这句话&am…

CString 与 LPCWSTR、LPSTR、char*、LPWSTR 等类型的转换

From&#xff1a;https://www.cnblogs.com/leanee/articles/2940088.html char [] 到 LPWSTR转换的一个具体应用&#xff1a;http://www.cppblog.com/lateCpp/articles/153358.html CString详细讲解&#xff1a;https://blog.csdn.net/qq_41786318/article/details/81989217 …

ofd电子文档内容分析工具(分析文档、签章和证书)

前言 ofd是国家文档标准&#xff0c;其对标的文档格式是pdf。ofd文档是容器格式文件&#xff0c;ofd其实就是压缩包。将ofd文件后缀改为.zip&#xff0c;解压后可看到文件包含的内容。 加入QQ交流群&#xff1a;618168615。获取下载程序。 ofd文件解压后&#xff0c;可以看到…

关于信任

[caption id"attachment_349" align"alignnone" width"374" caption"Trust is the most important thing to the team!"][/caption] 偶然间看到一张截图&#xff0c;是杭州小马哥不知何年何月何地做的show&#xff0c;这句话从他嘴里讲…

ES的安装和RestClient的操作

目录 初识elasticsearch 什么是elasticsearch elasticsearch的发展 Lucene的优缺点 elasticsearch的优势 倒排索引 es与mysql的概念对比 文档 索引 概念对比 架构 安装es 安装kibana 安装ik分词器 分词器 安装ik分词器 ik分词器的拓展和停用词典 操作索引库…

深度 | 智慧•城市,基于国际视野下的思考

来源&#xff1a;智慧城市决策参考智慧城市的兴起&#xff0c;得益于ICT技术的迅猛发展。经过这些年国内外诸多城市的探索和实践&#xff0c;智慧城市已经从最初的营销概念&#xff0c;逐渐发展成为一种支持城市发展的新理念。然而在实际应用中&#xff0c;智慧城市的内涵仍然是…

__cdecl、__stdcall、__fastcall 与 __pascal 浅析

X86调用约定 calling convention&#xff1a;https://www.cnblogs.com/shangdawei/p/3323252.html__cdecl、__stdcall、__fastcall 与 __pascal 浅析&#xff1a;https://www.cnblogs.com/yenyuloong/p/9626658.html王爽 汇编语言第三版 第9章 转移指令的原理&#xff1a;https…

全文详解:「深度学习」如何协助处理医疗中的「数据难题」

原文来源&#xff1a;WordPress作者&#xff1a;Luke Oakden-Rayner「雷克世界」编译&#xff1a;嗯~是阿童木呀、KABUDA、EVA医疗数据很难处理。在医学成像中&#xff0c;数据存储&#xff08;档案&#xff09;是基于临床假设进行操作的。不幸的是&#xff0c;这意味着当你想提…

Android应用程序变量

Android应用程序开发中&#xff0c;有的时候我们在应用程序的任何一个地方都需要访问一个全局变量&#xff0c;也就是在任何一个Activity中都可以访问的变量。它不会因为Activity的生命周期结束而消失。要实现应用程序级的变量&#xff0c;我们可以通过Application这个类来实现…

百度谷歌等联合推出机器学习基准 加速AI软硬件发展

来源&#xff1a;中国新闻网5月2日&#xff0c;由包括百度、谷歌、斯坦福大学、哈佛大学在内的多家企业和高校联合发布了一套用于测量和提高机器学习软硬件性能的国际基准MLPerf。其巨大的学术和产业价值获业界肯定&#xff0c;被认为不仅将加速推进机器学习硬件软件相关技术创…

王爽 汇编语言第三版 第10章 call 和 ret 指令 以及 子程序设计

第10章 call 和 ret 指令 10.1 ret 和 reft 指令 call 和 ret 指令都是转移指令&#xff0c;他们都修改 IP&#xff0c;或同事修改 CS 和 IP 。他们经常被共同来实现子程序的设计。 10.2 call 指令 和 根据位移 转移的call指令 段间转移 的 call 指令 转移地址 在 寄存器 中 的…

org/apache/maven/cli/MavenCli : Unsupported major.minor version 51.0

一、错误现象&#xff1a; 当改变了jdk版本时&#xff0c;在编译java时&#xff0c;会遇到Unsupported major.minor version错误。 jdk版本和stanford parser对应关系 JDK版本和Java编译器内部的版本号 J2SE 8 52, J2SE 7 51, J2SE 6.0 50, J2SE 5.0 49, JDK 1.4 48, J…

ip, tcp, udp, icmp header

Figure 1. IPv4 header Figure 2. TCP header Figure 3. UDP header Figure 4. ICMP header reference:TCP/IP Reference转载于:https://www.cnblogs.com/lbsx/archive/2010/11/30/1891814.html

人民日报三问人工智能,给法律制度带来哪些挑战?

来源&#xff1a;亿欧网 作者&#xff1a;倪弋摘要&#xff1a;人工智能生成物是否具有知识产权&#xff1f;人工智能可以替代司法者吗&#xff1f;人工智能侵权责任如何认定&#xff1f;人工智能的出现会给现行的法律制度带来了不少挑战&#xff0c;只有在法律研究上未雨绸缪…

测试用例设计--判定表

一. 判定表 定义判定表通常由四部分组成&#xff0c;如上图&#xff1a; 条件桩 : 它列出决定一组条件的对象&#xff1b; 条件项: 它列出各种可能的条件组合&#xff1b; 动作桩: 它列出所有的操作; 动作项: 它列出在对应的条件组合下的动作. 应用的范围在多个条件决定多个动…

王爽 汇编语言第三版 第11章 标志寄存器

条件码&#xff1a; ① OF(Overflow Flag)溢出标志&#xff0c;溢出时为1&#xff0c;否则置0.标明一个溢出了的计算&#xff0c;如:结构和目标不匹配.② SF(Sign Flag)符号标志&#xff0c;结果为负时置1&#xff0c;否则置0.③ ZF(Zero Flag)零标志&#xff0c;运算结果为0时…

Gartner:预计2018年人工智能行业总价值达1.2万亿美元

来源&#xff1a;网络大数据市场研究公司Gartner周三发布最新研究报告称&#xff0c;人工智能行业的总价值将在2018年达到1.2万亿美元&#xff0c;比2017年增长70%。其中&#xff0c;创造商业价值最大的领域是客户体验解决方案。该公司还预计&#xff0c;到2022年的时候&#x…