查看: 122|回复: 3

Python给PDF添加可见与隐藏数字签名实战教程

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
在处理合同、发票或报告时,数字签名能验证文档的完整性与签署人身份。相比手动在Acrobat里逐份签署,用Python批量处理更适合自动化流程。本文基于Spire.PDF for Python,详细介绍如何为PDF添加可见签名、隐藏签名、带时间戳的签名,以及验证签名有效性。

环境准备
首先安装依赖库:
  1. pip install Spire.Pdf
复制代码
还需要一个数字证书文件(.pfx或.p12格式)及对应的密码。测试阶段可使用自签名证书(如通过OpenSSL生成),生产环境应由CA签发。

添加可见的数字签名
可见签名会在PDF页面上绘制一个签名框,显示签署人、原因、位置等信息。核心是PdfOrdinarySignatureMaker对象,它负责加载证书并执行签署运算;签名外观通过PdfSignatureAppearance单独配置。
  1. from spire.pdf import *
  2. doc = PdfDocument()
  3. doc.LoadFromFile("SampleB_1.pdf")
  4. signatureMaker = PdfOrdinarySignatureMaker(doc, "Jerry.pfx", "e-iceblue")
  5. signature = signatureMaker.Signature
  6. signature.Name = "Jerry"
  7. signature.ContactInfo = "028-12345678"
  8. signature.Location = "Chengdu"
  9. signature.Reason = "文档负责人签署"
  10. appearance = PdfSignatureAppearance(signature)
  11. appearance.NameLabel = "签署人: "
  12. appearance.ContactInfoLabel = "联系方式: "
  13. appearance.LocationLabel = "地点: "
  14. appearance.ReasonLabel = "原因: "
  15. appearance.SignatureImage = PdfImage.FromFile("logo.png")
  16. appearance.GraphicMode = GraphicMode.SignImageAndSignDetail
  17. signatureMaker.MakeSignature("Signer:", doc.Pages.get_Item(0), 90.0, 550.0, 270.0, 90.0, appearance)
  18. doc.SaveToFile("DigitalSignature.pdf")
  19. doc.Dispose()
复制代码
关键点:
- Name、Reason、Location等信息写入签名对象,PDF阅读器可读取。
- GraphicMode设置签名框显示内容:SignImageAndSignDetail同时显示Logo和文字,也可只选图片或文字。
- MakeSignature坐标参数以点(point)为单位,原点在页面左下角(左下为(0,0)),四个数值依次为左边界、下边界、宽度、高度。

添加隐藏签名
若只需在文档层面完成完整性校验而不显示可见框,可创建不带外观的隐藏签名。同样使用PdfOrdinarySignatureMaker,只传签名字段名称即可。
  1. from spire.pdf import *
  2. doc = PdfDocument()
  3. doc.LoadFromFile("SampleB_1.pdf")
  4. signatureMaker = PdfOrdinarySignatureMaker(doc, "Jerry.pfx", "e-iceblue")
  5. signatureMaker.MakeSignature("signName")
  6. doc.SaveToFile("AddInvisibleSignature.pdf")
  7. doc.Dispose()
复制代码
隐藏签名仍具备防篡改能力,PDF阅读器可在签名面板中检测到它,但页面无任何显示。

添加带时间戳的签名
数字证书有有效期,若需证明签署发生在证书有效期内,需引入可信时间戳服务(TSA)。Security_PdfSignature提供ConfigureTimestamp方法指定TSA地址。
  1. from spire.pdf import *
  2. doc = PdfDocument()
  3. doc.LoadFromFile("SampleB_1.pdf")
  4. signature = Security_PdfSignature(doc, doc.Pages.get_Item(0), "Jerry.pfx", "e-iceblue", "signature")
  5. signature.Bounds = RectangleF(PointF(90.0, 550.0), SizeF(180.0, 90.0))
  6. signature.NameLabel = "Digitally signed by: Jerry"
  7. signature.Reason = "确保文档真实性"
  8. signature.DocumentPermissions = PdfCertificationFlags.AllowFormFill.value | PdfCertificationFlags.ForbidChanges.value
  9. signature.ConfigureTimestamp("https://freetsa.org/tsr")
  10. doc.SaveToFile("SignedByTimestamp.pdf")
  11. doc.Dispose()
复制代码
DocumentPermissions属性以证书化签名方式限定签署后允许的操作。示例组合表示“允许继续填写表单字段,但禁止其他改动”,适合审批后仍需收集信息且防止篡改的表单类文档。

验证已签名的文档
遍历PDF表单中的签名字段,调用VerifySignature方法检查文档完整性。
  1. from spire.pdf import *
  2. doc = PdfDocument()
  3. doc.LoadFromFile("SignedDocument.pdf")
  4. formWidget = PdfFormWidget(doc.Form)
  5. if formWidget.FieldsWidget.Count > 0:
  6.     for i in range(formWidget.FieldsWidget.Count):
  7.         field = formWidget.FieldsWidget.get_Item(i)
  8.         if isinstance(field, PdfField):
  9.             signatureField = PdfSignatureFieldWidget(field)
  10.             valid = doc.VerifySignature(signatureField.FullName)
  11.             print("签名有效" if valid else "签名无效")
  12. doc.Dispose()
复制代码
VerifySignature会重新计算文档摘要并与签名中的记录比对:若文档被修改,返回无效。

实用建议
- 证书密码不要硬编码:应通过环境变量或密钥管理服务读取。
- 坐标系统:签名框原点在页面左下角,y轴向上为正,与屏幕坐标相反,注意换算。
- 签名顺序:多签名时后续签名会包含先前签名内容,影响验证逻辑。
- 及时释放资源:处理完后调用Dispose(),避免批量任务文件句柄占用。

以上即为Python自动化添加PDF数字签名的完整实现。基于此,可进一步结合表单字段、长期验证(LTV)等构建合同管理、审批流转的自动签署方案。
回复

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Python给PDF添加可见与隐藏数字签名实战教程

很实用的教程,最近刚好在找给PDF批量签名的方案。请问自签名证书和CA签发的证书在功能上有哪些区别?除了信任问题外,在代码层面是否需要做不同处理?
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Python给PDF添加可见与隐藏数字签名实战教程

好实用的教程!Spire.PDF 这个库的可见/隐藏签名、时间戳绑定这些功能都讲得很清楚,坐标原点在左下角这个细节很多人会踩坑,楼主特意标出来太贴心了。要是能补充一下自签名证书用 OpenSSL 生成的具体命令就更完美了,感谢分享!
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Python给PDF添加可见与隐藏数字签名实战教程

谢谢分享,这篇教程非常实用,把可见签名、隐藏签名和带时间戳的签名的完整流程都讲清楚了,尤其是坐标原点在左下角这个细节,新手很容易忽略。想问下自签名证书用 OpenSSL 生成时,有没有推荐的参数设置,避免在验证时被识别为“不受信任”?另外,文中的时间戳服务 `freetsa.org` 是免费的吧,长期生产环境是否建议用固定的商业 TSA?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-7-17 11:48 , Processed in 0.035847 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部