更新 2024年十二月24日
分享:

对 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文档的三种主要方法

Signing MethodDescription
SignSign a PDF with a PdfSignature object
SignWithFileSign PDF with a digital signature certificate(.pfx or .p12) on disk
SignWithStoreSigns the PDF with digital signature extracted from your computer's signature storage. Based on a thumbprint ID

支持的数字签名证书文件

我们正式遵循X509Certificate2标准,并支持.pfx.p12签名。 如果您的签名无法直接应用于IronPDF的签名方法,您需要创建一个X509Certificate2证书,其说明可以在Microsoft文档中找到。

标志:从 X509Certificate2 创建 PdfSignature

IronPDF 的签名方法将接受 X509Certificate2 对象,其 X509KeyStorageFlags 设置为 Exportable

请注意

  • 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");

标志:为 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");

演示

您可能会看到感叹号或警告标志,而不是勾选标记。 这是因为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));

签名权限

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

定义

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

保存并签署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");

了解签名的增量保存方式

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

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

PDF Document IterationCertificate ACertificate BCertificate CCertificate D
0 (first save)
1
2
3
(form field edits only)

(form field edits only)
4 (only form fields edited)
5
(no further edits allowed)

(no further edits allowed)

(no further edits allowed)

以上是经过 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");

移除签名

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();

验证 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();

将签名盖章到PDF上

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

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

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");

输出结果

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


向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");
无署名签名

您可以在如何创建 PDF 表单文章中了解有关 IronPDF 及其支持的表单的更多信息。

查克尼特·宾

查克尼特·宾

软件工程师

 LinkedIn

Chaknith 负责 IronXL 和 IronBarcode 的工作。他在 C# 和 .NET 方面拥有深厚的专业知识,帮助改进软件并支持客户。他从用户互动中获得的洞察力,有助于提升产品、文档和整体体验。