开发技巧之PDF签章

我爱海鲸 2022-08-11 16:19:44 暂无标签

简介总结一位同事研究的一项开源的签章操作

1、资料准备

pom文件:

<!--itextPdf 依赖start-->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13.3</version>
</dependency>

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpkix-jdk15on</artifactId>
    <version>1.70</version>
</dependency>

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.70</version>
</dependency>

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>
<!--itextPdf 依赖end-->

资料准备:

资料地址

链接:https://pan.baidu.com/s/12wRos_422Y6ULySthAw63Q 
提取码:3dyb 

描述:源文件 = 源文件pdf

Demo3.pdf = 第一次签章

Demo4.pdf = 第二次签章(在第一次签章的基础上再签一次)

Tomcatocc.p12 通过jdk生成的p12证书

Demo3.asn = demo3.pdf /contents字典后面的二进制流的解码文件 (有注释,对应itext5源码)

Demo4.asn = demo4.pdf /contents 字典后面的二进制流的解码文件

ASN1.zip = ASN文件解码工具

2、pdf签章原理

通过文本编辑器(vscode)直接打开demo3.pdf直接查看流数据,会发现带有/sig

字典的数据 往右边看还有可以看到 /contents字典后面跟着一串流数据。那就是签章完之后的信息。国际规范为pkcs7结构体(demo3.asn)。实际上p7结构体是通过特定的asn.1结构组织而成,打个比方json = asn.1,接口报文 = p7结构体。这是两者的关系。

当然,对应的印章图片流就在/sig上面

其实p12证书也是由asn.1组成。

每次签章的时候,都会在pdf数据末尾添加一串签章信息,都是由/sig /contents等字典组成。/contents前面还有一个/bytesRange的字典,这个字典记录了签章的数据范围以及摘要的范围。使得每次签章的验签都是独立的(具体的话需要百度一下/byteRange字典的知识,我没完全理解)。

3、itext5签章流程

通过用户指定的摘要算法:

对pdf全文进行一次hash摘要。当然在执行这个摘要方法前需要调用一下preClose()方法。

下面是itext5 MakeSignature.java的源码

这个方法用来开辟/contents的预留空间(用来存放p7结构) 并生成/byteRange字典的范围。

紧接着就是加密摘要:

可以尝试把摘要流输出到控制台(需要拿到源码然后修改),你会发现上面的preClose方法做了些什么(就是上文所说)

4、验签

延签其实就是解析pdf文件里面的字典。关键的/sig、/byteRange、/contents。获取到/contents的数据流,反解析成asn.1的结构生成p7 一步步进行判断。(具体的看itext5源码)

验签描述的比较简单,实际详细理解需要进源码打断点

5、总结

Pdf签章流程大体分为:1、根据证书等信息生成预留的/contents的空间,确定好/byteRange的范围,对pdf原文进行hash摘要。通过pdf摘要、证书、等信息生成签名。一并保存到p7。然后再将p7保存到/contents的预留空间中。而验签就是泛解析/contents的数据流,生成p7,对原文再做一次hash摘要对比p7里面的

摘要判断是否被串改。以及签名的验证。多次签章的时候,摘要范围的判断是根据/byteRange的数据范围获取当前签章所属的摘要范围。P7里面存着许多信息,比如摘要算法的oid,签名算法的oid。都是用来为后续验签做好准备。里面还有各种的证书链(一般是根证书),和时间戳等信息,具体的看demo3.asn。以上是基于国际规范的pdf签章。而国密的签章由于技术壁垒问题,无法深入了解。单单是sm2证书的解析就能卡死我

你好:我的2025