您能建议一种修改此代码的方法,以便步骤(2)和(4)可以独立,并且不需要共享的PdfReader和PdfStamper实例吗?解决方案自己弄清楚了. 指向我的这段代码证明服务器上的进程必须是以下内容:获取未签名的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, os, 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)的存在.这使得使用此库比原来要困难和烦人得多.I'm developing a client-server application where clients have to sign PDF documents using their signatures and upload them to the server. The task is complicated by the fact that clients don't have the means to embed signatures into PDFs, they can only read raw bytes and produce the signature in the form of raw bytes.I'm trying to implement the following workflow:The client uploads the unsigned PDF to the serverThe server opens the PDF, extracts the bytes that the client needs to sign, and sends those bytes backThe client receives these bytes, signs them using a client certificate and sends the signature to the serverThe server embeds the received signature into the PDF it received earlier.I found some code samples of extracting bytes to sign and embedding the signature bytes into the PDF (this is the main sample I'm using).The problem is that this sample performs all the steps in one program, it embeds the signature right after getting the document hash without closing PdfStamper. What I need is some way to save the document after adding the signature field and getting sha.Hash, and then at some later time (when the server receives the computed signature) open the document and embed the signature value into the PDF.Can you suggest a way to modify this code so that the steps (2) and (4) can be independent, and not require shared instances of PdfReader and PdfStamper? 解决方案 Figured it out myself. This piece of code pointed me to the right direction.Turns out the process on the server has to be the following:Take the unsigned PDF and add an empty signature fieldCompute the bytes that need to be signed based on the modified content of the fileSave the modified PDF with an empty signature into a temporary fileSend the computed bytes to the clientWhen the client responds with the signature, open the temporary file and insert the signature into the field created earlierThe relevant server code: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, os, 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) { }}Side note: what bothers me in all those iText samples is the presence of magic numbers (like 8192 here) without any comments. This makes using this library so much more difficult and annoying than it could be. 这篇关于iTextSharp-如何获取PDF内容以进行签名,然后在以后进行签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!