简体   繁体   English

将数字签名的字段添加到PDF

[英]Add field for a digital signature to PDF

I create a new PDF file using PDFsharp and MigraDoc. 我使用PDFsharp和MigraDoc创建一个新的PDF文件。 Now I want to add a field where the user can click on it and select a certificate for digital signing the file. 现在我想添加一个字段,用户可以在其中单击该字段并选择用于对文件进行数字签名的证书。

I found in the web, that this should be possible with AcroForms. 我在网上发现,这应该可以用AcroForms。 But I wasn't able to use AcroForm because it is always null. 但是我无法使用AcroForm因为它总是为空。

My current example code: 我目前的示例代码:

Document document = new Document();

Section section = document.AddSection();
section.AddParagraph("Signature Test");


PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer(false, PdfFontEmbedding.Always);
pdfRenderer.Document = document;
pdfRenderer.RenderDocument();

// NullPointerException at the following line. AcroForm is null 
pdfRenderer.PdfDocument.AcroForm.Elements.Add(PdfAcroForm.Keys.SigFlags, new PdfInteger(3));

const string filename = "HelloWorld.pdf";
pdfRenderer.PdfDocument.Save(filename);
Process.Start(filename);

Why is this property null? 为什么这个属性为null? What can I do to set this to a correct value? 如何将其设置为正确值?

Or better, how can I add a field to select the digital certificate? 或者更好的是,如何添加字段来选择数字证书?

I found a solution that adds a signature field to the document. 我找到了一个为文档添加签名字段的解决方案。 Unfortunately I had to use reflection because auf missing access to the requried objects. 不幸的是我不得不使用反射,因为auf缺少对所需对象的访问权限。

using PdfSharp.Pdf;
using PdfSharp.Pdf.Annotations;
using System;
using System.Linq;
using System.Reflection;

internal sealed class MyPdfSignatureField : PdfAnnotation
{
    public MyPdfSignatureField(PdfDocument document, PdfRectangle rect) : base(document)
    {
        Elements.Add("/FT", new PdfName("/Sig"));
        Elements.Add(Keys.T, new PdfString("Signature1"));
        Elements.Add("/Ff", new PdfInteger(132));
        Elements.Add("/DR", new PdfDictionary());
        Elements.Add(Keys.Subtype, new PdfName("/Widget"));
        Elements.Add("/P", document.Pages[0]);


        PdfDictionary sign = new PdfDictionary(document);
        sign.Elements.Add(Keys.Type, new PdfName("/Sig"));
        sign.Elements.Add("/Filter", new PdfName("/Adobe.PPKLite"));
        sign.Elements.Add("/SubFilter", new PdfName("/adbe.pkcs7.detached"));
        sign.Elements.Add(Keys.M, new PdfDate(DateTime.Now));

        var irefTable = document
            .GetType()
            .GetField("_irefTable", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(document);
        var irefTableAdd = irefTable
            .GetType()
            .GetMethods()
            .Where(m => m.Name == "Add").Skip(1).FirstOrDefault();

        irefTableAdd.Invoke(irefTable, new object[] { sign });

        Elements.Add("/V", sign);

        Elements.Add("/Rect", rect);
        Flags = PdfAnnotationFlags.Print;
        Opacity = 1;
    }
}

And to use: 并使用:

var sig = new MyPdfSignatureField(document, new PdfRectangle(new XPoint(480, 33.75), new XPoint(612.2, 62.1)));
document.Pages[0].Annotations.Add(sig);

This is no very nice solution but it covers my basic requirements. 这不是一个很好的解决方案,但它涵盖了我的基本要求。 If you have some better idea, please let me know. 如果您有更好的想法,请告诉我。

This idea of this class comes from here: https://github.com/empira/PDFsharp/pull/11/files 这个类的想法来自这里: https//github.com/empira/PDFsharp/pull/11/files

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM