对 PDF 文档进行数字签名

This article was translated from English: Does it need improvement?
Translated
View the article in English

重要消歧义:签署PDF

开发者经常询问如何使用IronPDF通过编程方式向PDF文档添加签名。 通常来说,签名对不同的开发者有不同的含义:

  1. 使用证书对 PDF 文档进行数字签名,以确保其不会被篡改。

  2. 从图像文件向现有 PDF 添加图形手写签名图像。

  3. 在 PDF 文件上加盖证书图像。

  4. 在 PDF 中添加签名表单域,某些阅览器会提示签名。

    开始使用IronPDF

    立即在您的项目中开始使用IronPDF,并享受免费试用。

    第一步:
    green arrow pointer


使用数字证书签署PDF文件

IronPDF支持多种使用.pfx.p12格式的数字签名证书来签署PDF的方法。 在本操作指南中,将指导您了解用于数字签名 PDF 文档的所有**三种主要方法:

签署方法说明
标志PdfSignature 对象
签署文件使用磁盘上的数字签名证书(.pfx 或 .p12)对 PDF 进行签名
与商店签约使用从电脑签名存储区提取的数字签名签署 PDF。 基于拇指指纹识别

支持的数字签名证书文件

我们正式遵守 "X509Certificate2 "标准,并支持".pfx "和".p12 "签名。 如果您的签名无法在 IronPDF 的签名方法中直接应用,您需要创建一个 X509Certificate2 证书,具体说明可参阅微软文档.

标志:从 X509Certificate2 创建 PdfSignature

IronPDF 的签名方法将接受X509KeyStorageFlags设置为ExportableX509Certificate2对象。

请注意

  • IronPdf 仅支持 X509KeyStorageFlags.Exportable。 一些证书默认设置为可导出的KeyStorageFlags。 尝试使用不同的 KeyStorageFlags 将导致异常 => Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: 'The requested operation is not supported.'。

:path=/static-assets/pdf/content-code-examples/how-to/signing-X509Certificate2-with-privatekey.cs
using IronPdf;
using IronPdf.Signing;
using System.Security.Cryptography.X509Certificates;

ChromePdfRenderer renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>foo</h1>");

// Create X509Certificate2 object with X509KeyStorageFlags set to Exportable
X509Certificate2 cert = new X509Certificate2("IronSoftware.pfx", "123456", X509KeyStorageFlags.Exportable);

// Create PdfSignature object
var sig = new PdfSignature(cert);

// Sign PDF document
pdf.Sign(sig);

pdf.SaveAs("signed.pdf");
Imports IronPdf
Imports IronPdf.Signing
Imports System.Security.Cryptography.X509Certificates

Private renderer As New ChromePdfRenderer()
Private pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>foo</h1>")

' Create X509Certificate2 object with X509KeyStorageFlags set to Exportable
Private cert As New X509Certificate2("IronSoftware.pfx", "123456", X509KeyStorageFlags.Exportable)

' Create PdfSignature object
Private sig = New PdfSignature(cert)

' Sign PDF document
pdf.Sign(sig)

pdf.SaveAs("signed.pdf")
VB   C#

标志:为 PdfSignature 添加细粒度详情

在实例化PdfSignature时或实例化后,可向PdfSignature对象添加有用信息,包括日期、签名联系人、位置、签名原因、时间戳,以及在PDF文档上添加图像作为可视化外观。

提示
支持需要 SHA256 和 SHA512 的时间戳服务器

:path=/static-assets/pdf/content-code-examples/how-to/signing-add-granular-information.cs
using IronPdf;
using IronPdf.Signing;
using IronSoftware.Drawing;
using System;

ChromePdfRenderer renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>foo</h1>");

pdf.SaveAs("signed.pdf");

// Create PdfSignature object
var sig = new PdfSignature("IronSoftware.pfx", "123456");

// Add granular information
sig.SignatureDate = new DateTime(2000, 12, 02);
sig.SigningContact = "IronSoftware";
sig.SigningLocation = "Chicago";
sig.SigningReason = "How to guide";
sig.TimestampHashAlgorithm = TimestampHashAlgorithms.SHA256;
sig.TimeStampUrl = "http://timestamp.digicert.com";
sig.SignatureImage = new PdfSignatureImage("IronSoftware.png", 0, new Rectangle(0, 600, 100, 100));

// Sign and save PDF document
sig.SignPdfFile("signed.pdf");
Imports IronPdf
Imports IronPdf.Signing
Imports IronSoftware.Drawing
Imports System

Private renderer As New ChromePdfRenderer()
Private pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>foo</h1>")

pdf.SaveAs("signed.pdf")

' Create PdfSignature object
Dim sig = New PdfSignature("IronSoftware.pfx", "123456")

' Add granular information
sig.SignatureDate = New DateTime(2000, 12, 02)
sig.SigningContact = "IronSoftware"
sig.SigningLocation = "Chicago"
sig.SigningReason = "How to guide"
sig.TimestampHashAlgorithm = TimestampHashAlgorithms.SHA256
sig.TimeStampUrl = "http://timestamp.digicert.com"
sig.SignatureImage = New PdfSignatureImage("IronSoftware.png", 0, New Rectangle(0, 600, 100, 100))

' Sign and save PDF document
sig.SignPdfFile("signed.pdf")
VB   C#

演示

您可能会看到感叹号或警告标志,而不是勾选标记。 这是因为Adobe无法确认文件的真实性和完整性,因为证书不存在。 要获取复选标记,请将证书添加到Adobe并重新打开文档。

添加图片的不同方法

图像可以通过多种方式包含进来:

  • SignatureImage 属性设置为一个新的 PdfSignatureImage 对象。
  • 使用 LoadSignatureImageFromFile 方法从文件加载图像。LoadSignatureImageFromFile 支持多种图像格式。
  • 使用 LoadSignatureImageFromStream 方法从流中加载图像。 图像流可以从其他库生成,只要其格式为 TGA、PBM、TIFF、BMP、GIF、PNG、JPEG、Webp。
:path=/static-assets/pdf/content-code-examples/how-to/signing-add-image.cs
using IronPdf.Signing;
using IronSoftware.Drawing;

// Create PdfSignature object
var sig = new PdfSignature("IronSoftware.pfx", "123456");

// Add image by property
sig.SignatureImage = new PdfSignatureImage("IronSoftware.png", 0, new Rectangle(0, 600, 100, 100));

// Add image by LoadSignatureImageFromFile method
sig.LoadSignatureImageFromFile("IronSoftware.png", 0, new Rectangle(0, 600, 100, 100));

// Import image using IronSoftware.Drawing
AnyBitmap image = AnyBitmap.FromFile("IronSoftware.png");

sig.LoadSignatureImageFromStream(image.ToStream(), 0, new Rectangle(0, 600, 100, 100));
Imports IronPdf.Signing
Imports IronSoftware.Drawing

' Create PdfSignature object
Private sig = New PdfSignature("IronSoftware.pfx", "123456")

' Add image by property
sig.SignatureImage = New PdfSignatureImage("IronSoftware.png", 0, New Rectangle(0, 600, 100, 100))

' Add image by LoadSignatureImageFromFile method
sig.LoadSignatureImageFromFile("IronSoftware.png", 0, New Rectangle(0, 600, 100, 100))

' Import image using IronSoftware.Drawing
Dim image As AnyBitmap = AnyBitmap.FromFile("IronSoftware.png")

sig.LoadSignatureImageFromStream(image.ToStream(), 0, New Rectangle(0, 600, 100, 100))
VB   C#

签名权限

您可以明确指定证书保持有效的条件。 如果您希望您的签名在任何更改后失效,或只允许更改表单字段等,请使用下表查看选项:

PdfDocument.SignaturePermissions定义
不允许更改不得更改
允许填写表格允许更改表单字段值
允许填写表格和注释允许更改表单字段值和修改注释

该参数为可选参数,不设置该参数将应用认证特定修订版的签名,且该签名不可失效。

保存并签署PDF修订版本迭代

在下面的示例中,我们打开一个 PDF 文件,进行各种编辑,然后在保存前签名。 对于签名权限,我们只允许将表格填写作为未来的编辑内容; 否则,任何其他编辑都将导致签名无效。

然后我们将调用 SaveAsRevision 来将修订版保存到历史记录中,然后将新文档保存到磁盘上。

:path=/static-assets/pdf/content-code-examples/how-to/signing-revision.cs
using IronPdf;
using IronPdf.Rendering;

// Import PDF and enable TrackChanges
PdfDocument pdf = PdfDocument.FromFile("annual_census.pdf", TrackChanges: ChangeTrackingModes.EnableChangeTracking);
// ... various edits ...
pdf.SignWithFile("/assets/IronSignature.p12", "password", null, IronPdf.Signing.SignaturePermissions.AdditionalSignaturesAndFormFillingAllowed);

PdfDocument pdfWithRevision = pdf.SaveAsRevision();

pdfWithRevision.SaveAs("annual_census_2.pdf");
Imports IronPdf
Imports IronPdf.Rendering

' Import PDF and enable TrackChanges
Private pdf As PdfDocument = PdfDocument.FromFile("annual_census.pdf", TrackChanges:= ChangeTrackingModes.EnableChangeTracking)
' ... various edits ...
pdf.SignWithFile("/assets/IronSignature.p12", "password", Nothing, IronPdf.Signing.SignaturePermissions.AdditionalSignaturesAndFormFillingAllowed)

Dim pdfWithRevision As PdfDocument = pdf.SaveAsRevision()

pdfWithRevision.SaveAs("annual_census_2.pdf")
VB   C#

了解签名的增量保存方式

虽然 Chrome 浏览器等浏览器只能显示一个版本,但 PDF 文件可以存储文档的以前版本,类似于 Git 的提交历史记录。 您将在更高级的PDF查看器中看到这一点,例如Adobe Acrobat。

在处理PDF签名时,了解这一点很重要,因为对PDF的签名操作仅适用于PDF的当前版本。 您的PDF可能包含旧版本的签名,或者可能有几个未签名的版本。 我们可以举例说明如下:

PDF 文档迭代证书 A证书 B证书 C证书 D
(第一次保存)

(仅限表格字段编辑)

(仅限表格字段编辑)
(仅编辑表格字段)

(不允许进一步编辑)

(不允许进一步编辑)

(不允许进一步编辑)

以上是经过 6 次不同迭代的文档。 此文件可能在公司各部门之间流传,并在第3次迭代时得到批准并最终确定。在此迭代中,甲方和乙方在设置了“仅表单字段编辑”权限的情况下签署了该文件。 这意味着可以填写PDF文档中的表单字段,但任何对文档的其他更改将使它们的签名无效。

在上面的例子中,我们可以假设 C# 是填写表格并将其发回给 A、B 和 D 的人,他们都在文件上最后一次签署了 "不允许编辑 "的权限。 由于在此文件中未执行任何使其无效的操作,当我们运行IronPDF的签名方法时,我们将得到true

回滚到旧版本

要回滚到 PDF 的上一个版本,您可以使用 GetRevision 方法。 这将忽略自该版本以来所做的任何更改,包括较新的签名。 要做到这一点,请使用:

:path=/static-assets/pdf/content-code-examples/how-to/signing-revert-revision.cs
using IronPdf;

PdfDocument pdf = PdfDocument.FromFile("report.pdf");

int versions = pdf.RevisionCount; // total revisions

PdfDocument rolledBackPdf = pdf.GetRevision(2);
rolledBackPdf.SaveAs("report-draft.pdf");
Imports IronPdf

Private pdf As PdfDocument = PdfDocument.FromFile("report.pdf")

Private versions As Integer = pdf.RevisionCount ' total revisions

Private rolledBackPdf As PdfDocument = pdf.GetRevision(2)
rolledBackPdf.SaveAs("report-draft.pdf")
VB   C#

移除签名

IronPDF 有一个 RemoveSignatures 方法,可以删除 PDF 文档每个修订版本的所有签名。 用法如下:

:path=/static-assets/pdf/content-code-examples/how-to/signing-remove-signature.cs
using IronPdf;

PdfDocument pdf = PdfDocument.FromFile("invoice.pdf");
pdf.RemoveSignatures();
Imports IronPdf

Private pdf As PdfDocument = PdfDocument.FromFile("invoice.pdf")
pdf.RemoveSignatures()
VB   C#

验证 PDF 中的所有签名

调用 PDF 文档上的验证签名方法将查看所有文档版本的所有签名,并验证它们是否仍然有效。 这将返回一个bool值,如果全部有效则为true

:path=/static-assets/pdf/content-code-examples/how-to/signing-verify-signatures.cs
using IronPdf;

PdfDocument pdf = PdfDocument.FromFile("annual_census.pdf");
bool isValid = pdf.VerifyPdfSignatures();
Imports IronPdf

Private pdf As PdfDocument = PdfDocument.FromFile("annual_census.pdf")
Private isValid As Boolean = pdf.VerifyPdfSignatures()
VB   C#

将签名盖章到PDF上

首先,我将从我想要签名的PDF开始。 我将使用此示例发票:

我们将在PDF上应用一种以.png图片形式存在的手写签名。 这可能是手写签名或用于创建证书文件时使用的图像。这是我们将使用的样本签名:

Signature related to 将签名盖章到PDF上

代码

为此,我们将使用以下代码将手写签名作为水印印在 PDF 上:

:path=/static-assets/pdf/content-code-examples/how-to/signing-handwritten.cs
using IronPdf;
using IronPdf.Editing;

var pdf = PdfDocument.FromFile("invoice.pdf");

pdf.ApplyWatermark("<img src='signature.png'/>", 90, VerticalAlignment.Bottom, HorizontalAlignment.Right);

pdf.SaveAs("official_invoice.pdf");
Imports IronPdf
Imports IronPdf.Editing

Private pdf = PdfDocument.FromFile("invoice.pdf")

pdf.ApplyWatermark("<img src='signature.png'/>", 90, VerticalAlignment.Bottom, HorizontalAlignment.Right)

pdf.SaveAs("official_invoice.pdf")
VB   C#

输出结果

运行此代码后,我们将获得一个输出文件,文件底部右侧带有我们的签名。


向PDF添加一个未签名的签名字段

要添加未签名或空签名表单字段,必须首先通过实例化签名对象来创建签名表单字段。 接下来,在目标 PDF 文档中访问 Form 属性,并将新创建的签名对象传递给 Add 方法。 最后,导出带有空签名表单的 PDF。

:path=/static-assets/pdf/content-code-examples/how-to/signing-unsigned-signature.cs
using IronPdf;
using IronSoftware.Forms;

ChromePdfRenderer renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>testing</h1>");

// Configure required parameters
string name = "cert";
uint pageIndex = 0;
double x = 100;
double y = 600;
double width = 300;
double height = 100;

// Create signature
SignatureFormField signature = new SignatureFormField(name, pageIndex, x, y, width, height);

// Add signature
pdf.Form.Add(signature);

pdf.SaveAs("signature.pdf");
Imports IronPdf
Imports IronSoftware.Forms

Private renderer As New ChromePdfRenderer()
Private pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>testing</h1>")

' Configure required parameters
Private name As String = "cert"
Private pageIndex As UInteger = 0
Private x As Double = 100
Private y As Double = 600
Private width As Double = 300
Private height As Double = 100

' Create signature
Private signature As New SignatureFormField(name, pageIndex, x, y, width, height)

' Add signature
pdf.Form.Add(signature)

pdf.SaveAs("signature.pdf")
VB   C#
无署名签名

您可以在如何创建 PDF 表格文章