对 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 中添加签名表单域,某些阅览器会提示签名。

适用于PDF的C# NuGet库

安装使用 NuGet

Install-Package IronPdf
Java PDF JAR

下载 DLL

下载DLL

手动安装到你的项目中

适用于PDF的C# NuGet库

安装使用 NuGet

Install-Package IronPdf
Java PDF JAR

下载 DLL

下载DLL

手动安装到你的项目中

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

第一步:
green arrow pointer

查看 IronPDFNuget 用于快速安装和部署。它有超过800万次下载,正在使用C#改变PDF。

适用于PDF的C# NuGet库 nuget.org/packages/IronPdf/
Install-Package IronPdf

考虑安装 IronPDF DLL 直接。下载并手动安装到您的项目或GAC表单中: IronPdf.zip

手动安装到你的项目中

下载DLL

使用数字证书签署 PDF

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

签署方法说明
标志标志 a PDF with a Pdf标志ature object
标志WithFile标志 PDF with a digital signature certificate(.pfx or .p12) on disk
标志WithStore标志s the PDF with digital signature extracted from your computer's signature storage. 基于拇指指纹识别

支持的数字签名证书文件

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

Sign: Create PdfSignature From X509Certificate2

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

请注意

  • IronPDF 仅支持 X509KeyStorageFlags.Exportable。某些证书的 KeyStorageFlags 默认设置为 Exportable。尝试使用不同的 KeyStorageFlags 会导致异常 => Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException:"不支持请求的操作。

: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.FormFillingAllowed);

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.FormFillingAllowed)

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
0 (第一次保存)
1
2
3
(仅限表格字段编辑)

(仅限表格字段编辑)
4 (仅编辑表格字段)
5
(不允许进一步编辑)

(不允许进一步编辑)

(不允许进一步编辑)

上面是一份经过 6 次不同迭代的文档。这份文档可能会在公司各部门之间传递审批,直到迭代 3 最终完成。在这次迭代中,人员 A 和人员 B 都签署了该文档,并设置了 "仅限表单字段编辑 "权限。这意味着允许填写 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 "图像。这可以是手写签名,也可以是创建证书文件时使用的图像。这是我们将使用的签名样本:

代码

这样,我们就可以使用以下代码将手写签名作为水印印在 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 添加未签名的签名字段

目前尚不支持。有关 IronPDF 及其支持的表单的更多信息,请参阅 以编程方式在C#中填写PDF表单 文章