首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用追加模式属性后,iText7将签名转换为不可见签名

使用追加模式属性后,iText7将签名转换为不可见签名
EN

Stack Overflow用户
提问于 2019-12-15 18:25:09
回答 1查看 802关注 0票数 1

我遇到的问题是,如果在文档中创建签名字段时使用UseAppendMode属性,则它在签名时会创建不可见签名。否则,它将显示我的自定义签名外观的内容,并将一个可见签名创建为PDF。下面是我的代码片段:

代码语言:javascript
复制
SigningResponse signingResponse = new SigningResponse();
Stream outputStream = new MemoryStream();
Org.BouncyCastle.X509.X509Certificate x509Certificate = null;
int estimatedSize = SigningProfile.ContainsKey(ProfileCommon.DICTIONARY_SIZE.ToString()) ? 
    int.Parse(SigningProfile[ProfileCommon.DICTIONARY_SIZE.ToString()]) * 1024 : 600 * 1024;
Stream readerStream = new MemoryStream(documentBytes);
PdfReader pdfReader = new PdfReader(readerStream);
PdfSigner pdfSigner = new PdfSigner(pdfReader, outputStream, new StampingProperties().UseAppendMode());
pdfSigner.SetFieldName("Signature1");
pdfSigner.GetDocument().GetCatalog().SetModified();
if (signingRequest.CertifyPolicy != (int)CertifyPolicy.NOT_CERTIFIED)
    pdfSigner.SetCertificationLevel(signingRequest.CertifyPolicy);

PdfSignatureAppearance signatureAppearance = pdfSigner.GetSignatureAppearance();
signatureAppearance.SetContact("Contact Info");
signatureAppearance.SetLocation("Location");
signatureAppearance.SetPageNumber(1);
signatureAppearance.SetReason("Signing Reason");
PdfFormXObject n0 = signatureAppearance.GetLayer0();
float x = n0.GetBBox().ToRectangle().GetLeft();
float y = n0.GetBBox().ToRectangle().GetBottom();
float width = n0.GetBBox().ToRectangle().GetWidth();
float height = n0.GetBBox().ToRectangle().GetHeight();
PdfCanvas canvas = new PdfCanvas(n0, pdfSigner.GetDocument());
canvas.SetFillColor(ColorConstants.LIGHT_GRAY);
canvas.Rectangle(x, y, width, height);
canvas.Fill();
// Set the signature information on layer 2
PdfFormXObject n2 = signatureAppearance.GetLayer2();
Paragraph p = new Paragraph("This document was signed by Bruno Specimen.");
new Canvas(n2, pdfSigner.GetDocument()).Add(p);

signatureAppearance.SetCertificate(x509Certificate);
PreSigning external = new PreSigning(PdfName.Adobe_PPKLite, PdfName.Adbe_pkcs7_detached);
pdfSigner.SignExternalContainer(external, estimatedSize);
signingResponse.DocumentHash = external.getHash();
signingResponse.D2S = signingResponse.DocumentHash;
signingResponse.DocumentBytes = ((MemoryStream)outputStream).ToArray();
return signingResponse;

创建签名字段的代码如下:

代码语言:javascript
复制
byte[] documentBytes = null;
foreach (PDFSignatureField field in signatureFields)
{
    using (Stream memoryStream = new MemoryStream())
    using (PdfReader _pdfReader = new PdfReader(new MemoryStream(_documentBytes)).SetUnethicalReading(true))
    using (PdfDocument pdfDocument = new PdfDocument(_pdfReader, new PdfWriter(memoryStream)))
    {
        PdfAcroForm pdfAcroForm = PdfAcroForm.GetAcroForm(pdfDocument, true);
        //Initializing signature position object
        PDFSignaturePosition SigPosition = field.Position;
        for (int i = 0 ; i < SigPosition.Pages.Length ; ++i)
        {
            //Getting PDF document page
            PdfPage page = pdfDocument.GetPage(SigPosition.Pages[i]);
            if (page == null)
            {
                page = pdfDocument.GetPage(SigPosition.PageNumber);
            }
            //Getting PDF document page rotation
            int rotation = page.GetRotation();
            //Getting signature field rects according to PDF page
            iText.Kernel.Geom.Rectangle rect;
            if (rotation > 0 && SigPosition.Position == PDFSignaturePosition.DefaultSignaturePosition.Custom)
            {
                rect = GetSignaturePositionAccordingToRotation(SigPosition.Rect, page.GetCropBox(), rotation);
            }
            else
            {
                rect = GetSignaturePositionRect(SigPosition.Position, SigPosition.Rect, page.GetCropBox());
            }
            //Creating signature field into PDF page
            PdfFormField sig = PdfFormField.CreateSignature(pdfDocument, rect);
            //Setting signature field visible flag
            if (field.Display == (int)SignatureDisplayType.INVISIBLE)
            {
                sig.SetFieldFlags(PdfFormField.HIDDEN);
                sig.SetVisibility(PdfFormField.HIDDEN);
            }
            else
            {
                sig.SetFieldFlags(PdfFormField.VISIBLE);
            }
            //Setting signature field font information
            sig.Put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g"));
            //Setting signature field name
            sig.SetFieldName(i == 0 ? field.Name : field.Name + " - " + SigPosition.Pages[i]);
            //Setting signature field page
            sig.SetPage(SigPosition.Pages[i]);
            //Adding signature field into AcroForm
            pdfAcroForm.AddField(sig, page);
            //Making indirect reference of the added signature field into PDF
            sig.MakeIndirect(pdfDocument);
            //Closing PDF document object
            pdfDocument.Close();
            //Getting latest document bytes after adding PDF field
            documentBytes = ((MemoryStream)memoryStream).ToArray();
            if (i + 1 == SigPosition.Pages.Length)
            {
                break;
            }
        }
        _documentBytes = documentBytes;
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-17 16:50:42

由于您使用了大量定义、声明和填充在您显示的代码之外的变量,所以我不得不大大减少代码。此外,我没有您的示例文档来进行测试,因此,必须用我手头的文档进行测试。

尽管如此,我还是可以重现这个问题,并在我的设置中找到了解决方案。我希望,尽管在设置上的所有差异,您可以使用这个解决方案。

签名字段在我的设置中变得不可见的原因是,当以附加模式将签名字段添加到文档时,文档范围内的字段数组没有被标记为修改。另一方面,签名者则依赖于签名字段来签名,以便在字段数组中找到签名。因此,签名者没有找到准备好的可见字段,而是创建了一个新的、不可见的字段。

解决方法是手动将所讨论的数组标记为修改后的数组:

代码语言:javascript
复制
pdfAcroForm.GetPdfObject().Get(PdfName.Fields).SetModified();
pdfAcroForm.GetPdfObject().SetModified();

//Closing PDF document object
pdfDocument.Close();
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59346843

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档