将数字签名字段添加到 PDF
Add field for a digital signature to PDF
我使用 PDFsharp 和 MigraDoc 创建了一个新的 PDF 文件。
现在我想添加一个用户可以点击它的字段和 select 一个用于对文件进行数字签名的证书。
我在网上发现,这应该可以通过 AcroForms 实现。
但是我无法使用 AcroForm
因为它总是空的。
我当前的示例代码:
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);
为什么这个 属性 是空的?我该怎么做才能将其设置为正确的值?
或者更好的是,如何向 select 数字证书添加一个字段?
我找到了一个向文档添加签名字段的解决方案。不幸的是,我不得不使用反射,因为 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;
}
}
并使用:
var sig = new MyPdfSignatureField(document, new PdfRectangle(new XPoint(480, 33.75), new XPoint(612.2, 62.1)));
document.Pages[0].Annotations.Add(sig);
这不是一个很好的解决方案,但它满足了我的基本要求。如果你有更好的想法,请告诉我。
这个class的想法来自这里:https://github.com/empira/PDFsharp/pull/11/files
我使用 PDFsharp 和 MigraDoc 创建了一个新的 PDF 文件。 现在我想添加一个用户可以点击它的字段和 select 一个用于对文件进行数字签名的证书。
我在网上发现,这应该可以通过 AcroForms 实现。
但是我无法使用 AcroForm
因为它总是空的。
我当前的示例代码:
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);
为什么这个 属性 是空的?我该怎么做才能将其设置为正确的值?
或者更好的是,如何向 select 数字证书添加一个字段?
我找到了一个向文档添加签名字段的解决方案。不幸的是,我不得不使用反射,因为 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;
}
}
并使用:
var sig = new MyPdfSignatureField(document, new PdfRectangle(new XPoint(480, 33.75), new XPoint(612.2, 62.1)));
document.Pages[0].Annotations.Add(sig);
这不是一个很好的解决方案,但它满足了我的基本要求。如果你有更好的想法,请告诉我。
这个class的想法来自这里:https://github.com/empira/PDFsharp/pull/11/files