import os from pyhanko import stamp from pyhanko.pdf_utils import text from pyhanko.pdf_utils.font import opentype from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter from pyhanko.sign import fields, signers from pyhanko.sign import timestamps from pyhanko.sign.fields import SigSeedSubFilter import uuid
in_file = input("Location of input pdf: ").strip()
target = input('Who is this document given to? (Myself by default) ').strip()
if target == '': target = 'Myself'
purpose = input( 'The reason why you want to sign the document?(Not Specified by default) ').strip()
if purpose == '': purpose = 'Not Specified'
desc = input('Any other information you want to give? If not, hit Enter.').strip()
filename = os.path.basename(in_file)
withopen(in_file, 'rb') as inf: w = IncrementalPdfFileWriter(inf, strict=False) fields.append_signature_field( w, sig_field_spec=fields.SigFieldSpec( # x1,y1,x2,y2 left to right, bottom to top 'Signature', box=(395, 750, 580, 830) ) )
meta = signers.PdfSignatureMetadata(field_name='Signature', md_algorithm='sha256', subfilter=SigSeedSubFilter.PADES, embed_validation_info=False, use_pades_lta=True,) pdf_signer = signers.PdfSigner( meta, timestamper=timestamper, signer=signer, stamp_style=stamp.QRStampStyle( # Let's include the URL in the stamp text as well stamp_text='Signed by: %(signer)s\nEmail: %(email)s\nTime: %(ts)s\nURL: '+ url + \ '\nUUID: \n%(uuid)s\n' + extra_info, text_box_style=text.TextBoxStyle( font=opentype.GlyphAccumulatorFactory( '/home/micraow/.local/Rajdhani-Medium.ttf') # 字体位置 ), ), )
id = uuid.uuid1()
info = "如果你看到这段文字,它意味着这个文件经过了数字签名。\nIf you see this text, it means the document has been digitally signed.\n" + \ "签名人 The signer: " + signer_name + '\n'+'原始文件名 Original filename: ' + \ filename+'\n'+'文档接收方 Target: ' + target + \ '\n'+'文档签名原因 Reason: ' + purpose + '\n'
if desc != '': info = info + '更多信息 More information: ' + desc+'\n'
info = info + '这个文档使用了由Pengbo提供的工具进行签名,有关该签名的细节你可以在https://pengs.top/pdf-sign/ 看到。\n This document is signed using the tools provided by Pengbo, details of which can be found at https://pengs.top/pdf-sign/.' withopen(output_dir+"signed_"+filename, 'wb') as outf: # with QR stamps, the 'url' text parameter is special-cased and mandatory, even if it # doesn't occur in the stamp text: this is because the value of the 'url' parameter is # also used to render the QR code. pdf_signer.sign_pdf( w, output=outf, appearance_text_params={ 'signer': signer_name, 'email': email, 'url': info, 'uuid': str(id)} )
print("File at: "+output_dir+"signed_"+filename)
有一些需要注意的:
import下面一堆信息根据自己实际情况改
如果附加信息太多,二维码可能不好扫。
运行前确保output_dir存在,不存在请新建文件夹,
Windows上路径需要转义,你需要在路径中每个反斜杠后再加一个反斜杠。
路径可用相对路径或绝对路径,
linux上,可以将文件拖到终端窗口中快捷输入路径。
对了,关于上面提到的的时间戳
时间戳通常包含以下几个关键要素:
具体的时间信息:精确到秒甚至更高精度的时间点,明确标识了签名动作发生的时刻。
例如,时间戳可能记录为“2024 年 7 月 3 日 15 时 30 分 25 秒”。
数字签名:用于证明时间信息的完整性和准确性,防止被篡改。
这确保了记录的时间是真实和可信的。
权威认证:时间戳通常由可信赖的第三方时间戳服务器生成和提供。
这个服务器具有高度准确的时钟和安全机制,以确保其提供的时间信息是准确和不可伪造的。
举例来说,当对一份 PDF 文档进行签名时,时间戳就像一个公证员在旁边记录下您签名的精确时间,并给这个时间记录加上了一个无法篡改的印章,以证明这个时间的真实性和有效性。