使用附加模式属性后,iText7将签名转换为不可见签名 [英] iText7 converting signature as an invisible signature after using append mode property

查看:241
本文介绍了使用附加模式属性后,iText7将签名转换为不可见签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am getting issue that if I use UseAppendMode property while creating signature field in the document, upon signing it creates invisible signature. Otherwise it displays the content of my custom signature appearance and creates a visible signature into PDF. Following is my code snippet:

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;

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

And the code of creating signature field is as follows:

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;
    }
}

推荐答案

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

尽管如此,我仍然可以重现该问题并在我的设置中找到解决方案.我希望尽管设置有所不同,您仍然可以使用此解决方案.

导致签名字段在我的设置中不可见的原因是,在以附加模式将签名字段添加到文档中时,文档范围的 AcroForms中的 Fields 数组字典未标记为已修改.另一方面,签名者依靠签名字段进行签名,以便在该 Fields 数组中找到该签名.因此,签名者没有找到准备好的可见字段,而是使用该名称创建了一个新的不可见字段.

The reason for the signature field becoming invisible in my setup turned out to be that while adding the signature fields to the document in append mode, the Fields array in the document-wide AcroForms dictionary was not marked as modified. The signer on the other hand relies on the signature field to sign to be found in that Fields array. The signer, therefore, did not find the prepared, visible field and created a new, invisible field with that name.

一种解决方法是将有问题的阵列手动标记为已修改:

A work-around is to manually mark the array in question as modified:

pdfAcroForm.GetPdfObject().Get(PdfName.Fields).SetModified();
pdfAcroForm.GetPdfObject().SetModified();

//Closing PDF document object
pdfDocument.Close();

这篇关于使用附加模式属性后,iText7将签名转换为不可见签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆