我正在开发一个客户端 – 服务器应用程序,客户端必须使用签名对PDF文档进行签名并将其上载到服务器.由于客户端无法将签名嵌入到PDF中,因此它们只能读取原始字节并以原始字节的形式生成签名,这使得任务变得复杂.
我正在尝试实现以下工作流程:
>客户端将未签名的PDF上载到服务器
>服务器打开PDF,提取客户端需要签名的字节,然后将这些字节发回
>客户端接收这些字节,使用客户端证书对其进行签名,然后将签名发送到服务器
>服务器将收到的签名嵌入到之前收到的PDF中.
我发现了一些提取字节的代码示例,用于签名并将签名字节嵌入PDF(this is the main sample I’m using).
问题是这个示例执行一个程序中的所有步骤,它在获取文档哈希后立即嵌入签名而不关闭pdfstamper.我需要的是在添加签名字段并获取sha.Hash之后保存文档的某种方式,然后在稍后的某个时间(当服务器收到计算的签名时)打开文档并将签名值嵌入到PDF中.
您能否建议一种修改此代码的方法,以便步骤(2)和(4)可以独立,并且不需要PdfReader和pdfstamper的共享实例?
解决方法
自己搞清楚了.
This piece of code向我指出了正确的方向.
原来服务器上的进程必须如下:
>获取未签名的PDF并添加一个空的签名字段
>根据文件的修改内容计算需要签名的字节
>将带有空签名的已修改PDF保存到临时文件中
>将计算的字节发送到客户端
>当客户端使用签名响应时,打开临时文件并将签名插入到先前创建的字段中
相关的服务器代码:
public static byte[] GetBytesToSign(string unsignedPdf,string tempPdf,string signatureFieldName) { using (PdfReader reader = new PdfReader(unsignedPdf)) { using (FileStream os = File.OpenWrite(tempPdf)) { pdfstamper stamper = pdfstamper.CreateSignature(reader,os,'\0'); PdfSignatureAppearance appearance = stamper.SignatureAppearance; appearance.SetVisibleSignature(new Rectangle(36,748,144,780),1,signatureFieldName); IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.AdobE_PPKMS,PdfName.ADBE_PKCS7_SHA1); MakeSignature.SignExternalContainer(appearance,external,8192); return SHA1Managed.Create().ComputeHash(appearance.GetRangeStream()); } } } public static void EmbedSignature(string tempPdf,string signedPdf,string signatureFieldName,byte[] signedBytes) { using (PdfReader reader = new PdfReader(tempPdf)) { using (FileStream os = File.OpenWrite(signedPdf)) { IExternalSignatureContainer external = new MyExternalSignatureContainer(signedBytes); MakeSignature.SignDeferred(reader,signatureFieldName,external); } } } private class MyExternalSignatureContainer : IExternalSignatureContainer { private readonly byte[] signedBytes; public MyExternalSignatureContainer(byte[] signedBytes) { this.signedBytes = signedBytes; } public byte[] Sign(Stream data) { return signedBytes; } public void ModifySigningDictionary(PdfDictionary signDic) { } }
旁注:在所有这些iText样本中困扰我的是魔术数字的存在(如8192这里),没有任何评论.这使得使用这个库变得更加困难和烦人.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。