需求描述
最近来了一个需求,客户要在 10 份 PDF 上使用电子签名,签完了以后还要合并再进行一次总的签名
众所周知,电子签名当文档本身内容发生变化后,它的 hash 值就变了,和电子签名存储的 hash 值不一致,电子签名就失效了,客户觉得这个失效很难看,希望能保留印章图片,去除签名证书
pdfbox 简单介绍
pdfbox 是一个支持 PDF 文档开发转换的 java 开源库
在我看来,这个开源库最棒的功能就是
- 分割和合并 PDF 文档
- 将 PDF 保存为图片
思路简单描述
PDF 的数据结构可以这样理解,文档的内容中,所有的文本,图片,签名都是一个个对象,对象直接有互相的引用,签名相当于一个图片对象,对象包含了一个引用对象,引用指向一个签名证书对象,签名证书对象也包含一个指向图片对象的引用对象。
我的思路就是过滤出签名证书,直接把这些签名对象删掉,这样就能只保留图片了。
需要说明的是这只是我的简单理解。
代码实现
public class DocumentConvertNoCert {
public static void convertNoCert(OutputStream os, byte[] file) {
PDDocument pdDocument;
try {
pdDocument = PDDocument.load(file);
PDDocumentCatalog documentCatalog = pdDocument.getDocumentCatalog();
PDAcroForm acroForm = documentCatalog.getAcroForm();
PDFieldTree fieldTree = acroForm.getFieldTree();
List<PDField> fields = new ArrayList<>();
for (PDField pdField : fieldTree) {
if (pdField instanceof PDSignatureField){
fields.add(pdField);
}
}
acroForm.flatten(fields,true);
pdDocument.save(os);
pdDocument.close();
} catch (IOException e) {
throw new BizException("转换无证书文档失败",e);
}
}
}
最终效果
我本地的旧版 Adobe pdf 阅读器对于签名图片的点击没有反应,和普通图片一样。
客户的新版 pdf 阅读点击签名图片时会显示签名数据错误。
之后使用 Adobe pdf 阅读器进行文件合并后,文件就看上去正常了,也可以继续正常地签名。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于