前段根据公司需求,要对PDF进行电子签名,后来就研究了一下,又借鉴了一下java的itext开源库,最后查看了Apple的官方文档,各种方式寻找解决方案,最后发现OC并没有提供类似于itext的方法。
其实本质就把签名值、签名者信息、时间、地点、公司等信息,存入一个字典,放入到PDF的Perms目录下。根据官方给的方法使用CGPDFDocumentRef,可读取到PDF结构目录,但是没有一个Perms目录,想尝试把签名数据封装一下,然后增加一个也不能,最后没有办法最后只能在移动端获取PDF文件签名值,然后传给后台,让后台使用itext进行电子签名操作,。
PDF文件签名值
其实就是解析PDF文档目录,获取到Contents目录下的内容,如果有多页,要获取每页的content内容,然后对整体内容进行摘要算法,获取到摘要值,然后在对摘要值进行签名运算(其实就是做个非对称加密,保证摘要值在传输过程中不被修改,我这边使用的是sm2。你也可以省去这一步,直接把摘要值给后台),最后把加密后的签名值传给服务器。获取pdf Contents内容的原因是,进行摘要算法,就是防止pdf上数据发生变化。类似于MD比对照片文档是否发生修改一样。
摘要值说明:Contents内包含了构成一个PDF内容所有数据,比如标题内容、字体大小、字体颜色、坐标等信息,如果对PDF修改了,那么它的contents肯定也会发生改变,自然而然获取的摘要值也就发生了改变,电子签名的本质就是在签名后,防止被串改。
简单说一下PDF电子签名的流程
1、首先要下载PDF,然后对PDF进行图片签名或者文字签名都可以(注意添加签名时,PDF的坐标系是左下角为原点,与view的左上角原点不一样,所以要注意坐标转换)
2、通过CGPDFDocumentRef获取到,每页的PDF的content,然后拼接每页的内容(也可以单独对每页进行摘要,生成一个数组摘要),使用摘要算法对整个PDF内容进行一个摘要处理,我这边使用的sm3摘要算法
读取PDF目录结构如下:
3、获取到摘要值,然后对摘要值进行签名算法,获取到签名值(根据项目安全性要求,决定是否要做签名算法,就是对摘要值加密),摘要值就是你要放入PDF文档目录结构内的数据
4、你可以在移动端调用 C 的方法,构成一个PDKS7结构传给后台,或者直接让后台用itext生成 ,API都是有这个的。PKCS7规范不是太了解,可以自己查一下,这个里面有证书、签名人、签名时间等签名信息。
-
贴张图,这张图是用itext的软件打开,已经有签名信息的PDF,Perms这目录如果有签名值就有这个目录,如果没有这个目录就不存在,开始我就想找看看oc有没有提供添加目录的方法,但是并没有找到,具体可以查看官方文档下CGPDFDocumentRef的方法:
ItextPDF.png -
这个是用itext签完名后,在window下查看PDF签名信息,证书信息等
签名信息查看
大概就是这个流程,OC这边确实是没是想方法,最后附上封装的读取PDF文档目录项目工程:PDF目录解析。
如果有好的解决方式,期望指导。
网友评论