该页面可以包含自动翻译的文本。

在 C# 和 VB.NET 中签署 PDF 文档

数字签名用于验证用户身份和 PDF 文档内容。签名可用于证明该 PDF 文档:

  • 自签名后未被修改。
  • 由特定人员进行数字签名。

在 C# 和 VB.NET 中向 PDF 添加数字签名

用于签署 PDF 文档的 .NET 库

使用 Docotic.Pdf 库 在 .NET Framework 和 .NET Core 应用程序中签署 PDF 文档。可在 下载 C# .NET PDF 库 页面获取该库和免费限时许可证密钥。

Docotic.Pdf 可以使用不同的摘要算法(SHA-1、SHA-256、SHA-384、SHA-512、RIPEMD-160)和不同的签名格式(adbe.pkcs7.detached 或 ETSI.CAdES.detached)创建数字签名。该库还可以 验证 PDF 签名

在 C# 中添加数字签名

你需要由有效证书颁发机构(CA)签发的数字 PKCS#12 证书(.pfx 或 .p12 文件)来签署 PDF 文档。下面是一个在 C# 中签署 PDF 文档的基本示例:

using BitMiracle.Docotic.Pdf;

using var pdf = new PdfDocument("document_to_sign.pdf");
var options = new PdfSigningOptions("your_cert.p12", "your_cert_password")
{
    DigestAlgorithm = PdfDigestAlgorithm.Sha256,
    Format = PdfSignatureFormat.Pkcs7Detached,
    Reason = "Testing digital signatures",
    Location = "My workplace",
    ContactInfo = "support@example.com"
};

pdf.SignAndSave(options, "signed.pdf");

将 "your_cert.p12" 和 "your_cert_password" 替换为你自己的 .p12 或 .pfx 证书文件和密码。在 GitHub 上,你可以下载并试用完整的 签署 PDF 文档 示例,适用于 C# 和 VB.NET。

有些情况下,你需要签署已经签过名的文档。或者,多个人需要依次签署同一个表单。这也可以实现。步骤基本相同。只需确保以增量方式签名并保存。只要你只应用允许的更改,增量更新不会使数字签名失效。

在 C# 和 VB.NET 中,还有 签署已经签过名的 PDF 文档由多人签署 PDF 表单 示例,适用于这些情况。

上面的代码会隐式向 PDF 文档添加一个不可见的签名字段,并使用它进行签名。下面我们来看如何在 PDF 中添加并自定义签名字段。

带手写签名图像的 PDF 签名

你通常需要在数字签名之外再向 PDF 添加手写签名图像。此示例展示了如何在 C# 中添加带关联图像的数字签名:

using var pdf = new PdfDocument("document_to_sign.pdf");
var options = new PdfSigningOptions("your_cert.p12", "your_cert_password")
{
    DigestAlgorithm = PdfDigestAlgorithm.Sha256,
    Format = PdfSignatureFormat.Pkcs7Detached,
};

PdfSignatureField field = pdf.Pages[0].AddSignatureField(20, 20, 100, 50);
options.Field = field;

PdfImage image = pdf.CreateImage("your_signature.jpg");
options.Appearance.Image = image;
options.Appearance.HideAllText();

pdf.SignAndSave(options, "signed.pdf");

这段代码会添加一个签名字段,将该字段与签名选项关联,并自定义字段外观。你可以在签名字段中显示文本、图像,或两者同时显示。有关更多细节,请查看 PdfSignatureAppearanceOptions 类使用自定义样式为签名字段签名 示例。

使用签名字段锁定 PDF 表单字段

签名字段可用于在签名后锁定 PDF 表单字段。此示例展示了如何在 C# 中于签名后锁定特定表单字段:

var first = page.AddSignatureField("first", 100, 100, 200, 50);

// 当第一个字段签名后,名称为 "some_text_field" 和
// "some_checkbox" 的字段将被锁定,无法编辑
first.Lock = PdfSignatureFieldLock.CreateLockFields("some_text_field", "some_checkbox");

下面的代码展示了如何在签名后锁定所有表单字段:

var second = page.AddSignatureField("second", 100, 200, 200, 50);

// 当第二个字段签名后,所有字段都将被锁定,无法编辑
second.Lock = PdfSignatureFieldLock.CreateLockAll();

你还可以锁定 PDF 文档中的所有表单字段,但排除指定字段。可使用 PdfSignatureFieldLock.CreateLockAllExceptFields 方法

可从 GitHub 下载并试用完整的 带锁签署签名字段 示例,适用于 C# 和 VB.NET。

在数字签名中嵌入时间戳

你可以通过嵌入时间戳来增强数字签名的安全性。为此,请将 Timestamp Authority URL 指定为签名选项之一。如果需要,还可以提供用户名和密码。

签名时,库会从 Timestamp Authority 获取时间戳并将其嵌入签名中。

出于兼容性原因,我们建议对带时间戳的签名使用 SHA 摘要算法之一。

// 将下面的测试 URL 替换为你的时间戳机构 URL
options.Timestamp.AuthorityUrl = new Uri("http://tsa.starfieldtech.com/");

// 如果你的时间戳机构需要身份验证,请指定用户名和密码
options.Timestamp.Username = null;
options.Timestamp.Password = null;