对 PDF 文档进行数字签名
重要消歧义:签署PDF
开发者经常询问如何使用IronPDF通过编程方式向PDF文档添加签名。 通常来说,签名对不同的开发者有不同的含义:
- 在 PDF 中添加签名表单域,某些阅览器会提示签名。
开始使用IronPDF
立即在您的项目中开始使用IronPDF,并享受免费试用。
如何用 C# 签署 PDF 文件
使用数字证书签署PDF文件
IronPDF支持多种使用.pfx
和.p12
格式的数字签名证书来签署PDF的方法。 在本操作指南中,将指导您了解用于数字签名 PDF 文档的所有**三种主要方法:
签署方法 | 说明 |
---|---|
标志 | 用 PdfSignature 对象 |
签署文件 | 使用磁盘上的数字签名证书(.pfx 或 .p12)对 PDF 进行签名 |
与商店签约 | 使用从电脑签名存储区提取的数字签名签署 PDF。 基于拇指指纹识别 |
支持的数字签名证书文件
我们正式遵守 "X509Certificate2 "标准,并支持".pfx "和".p12 "签名。 如果您的签名无法在 IronPDF 的签名方法中直接应用,您需要创建一个 X509Certificate2
证书,具体说明可参阅微软文档.
标志:从 X509Certificate2 创建 PdfSignature
IronPDF 的签名方法将接受X509KeyStorageFlags设置为Exportable的 X509Certificate2
对象。
请注意
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")
标志:为 PdfSignature 添加细粒度详情
在实例化PdfSignature时或实例化后,可向PdfSignature对象添加有用信息,包括日期、签名联系人、位置、签名原因、时间戳,以及在PDF文档上添加图像作为可视化外观。
提示
: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")
演示
您可能会看到感叹号或警告标志,而不是勾选标记。 这是因为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))
签名权限
您可以明确指定证书保持有效的条件。 如果您希望您的签名在任何更改后失效,或只允许更改表单字段等,请使用下表查看选项:
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")
了解签名的增量保存方式
虽然 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")
移除签名
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()
验证 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()
将签名盖章到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")
输出结果
运行此代码后,我们将获得一个输出文件,文件底部右侧带有我们的签名。
向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")
您可以在如何创建 PDF 表格文章