如何使用 C## 使用 HSM 对 PDF 进行数字签名

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

IronPDF 可通过 PKCS#11 API 使用硬件安全模块 (HSM) 实现安全的 PDF 签名,私钥永远不会离开物理设备,为需要防篡改数字签名的关键任务应用程序提供银行级别的安全性。

as-heading:2(快速入门:在 C# 中使用 HSM 签署 PDF)

1.通过 NuGet 安装 IronPdf:Install-Package IronPdf 2.配置您的 HSM 设备(或使用 SoftHSM 进行测试) 3.使用您的 HSM 凭据创建 UsbPkcs11HsmSigner

Nuget Icon立即开始使用 NuGet 创建 PDF 文件:

  1. 使用 NuGet 包管理器安装 IronPDF

    PM > Install-Package IronPdf

  2. 复制并运行这段代码。

    var hsmSigner = new UsbPkcs11HsmSigner(libraryPath, pin, tokenLabel, keyLabel);
  3. 部署到您的生产环境中进行测试

    立即开始在您的项目中使用 IronPDF,免费试用!
    arrow pointer

4.生成 PDF 并签名:

   var pdf = renderer.RenderHtmlAsPdf("<h1>Document</h1>");
   pdf.SignAndSave("signed.pdf", hsmSigner);
   var pdf = renderer.RenderHtmlAsPdf("<h1>Document</h1>");
   pdf.SignAndSave("signed.pdf", hsmSigner);
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Document</h1>")
pdf.SignAndSave("signed.pdf", hsmSigner)
$vbLabelText   $csharpLabel

5.在 PDF 查看器中验证签名

在很多应用程序中,为 PDF 文档添加签名是一项常见需求。 然而,关键任务应用程序需要更高的安全性,密钥不能被篡改。 使用.pfx文件进行正常的签名操作就像在家中拥有一把万能钥匙。 应用程序将密钥加载到内存中以签署文档。 如果计算机被入侵,密钥可能会被盗。

更安全的替代方法是使用硬件安全模块 (HSM)。 使用 HSM(如 USB 令牌)时,私钥在设备内部生成,不能离开设备。

这个过程就像把文件带到银行一样。 应用程序提供一个 PIN 码,HSM 会将文档带入保管库,用密钥加盖印章,然后返回加盖印章的文档。 钥匙永远不会离开保险库。 这将提供额外的安全性,因为密钥不会被复制或盗取。

如何使用 HSM 签署 PDF?

使用 HSM 进行签名通常需要一个物理设备,例如 USB 令牌,应用程序需要与该设备进行交互。 IronPdf 与这些操作兼容,因为库和标准 HSM 都使用 PKCS#11 作为通用 API。 为便于演示,本指南使用了模拟 HSM 而非实体 HSM。

在生产或实时测试环境中,您不应使用此模拟。 请使用您的实际 HSM。 对于生产环境,请考虑实施额外的PDF 安全功能,例如密码保护和权限以及 HSM 签名,以实现全面的文档保护。

要运行此模拟,您必须首先安装SoftHSMOpenSSLOpenSC以生成必要的密钥和令牌。 有关使用 SoftHSM 的更多信息,请参阅其 GitHub 公共仓库。

在实施 HSM 签名之前,请确保您已正确安装 IronPDF并配置了许可证密钥以用于生产。

首先从 HTML 字符串创建 PDF。 在下面的示例中,我们定义了模拟 SoftHSM 的路径和凭据。 这包括提供您创建的 SoftHSM .dll库文件和.crt证书文件的绝对路径。

接下来,指定输出路径,本例中为 output.pdf。

定义三个字符串:hsmTokenLabelhsmPinhsmKeyLabel。 这些字符串区分大小写,并且必须与您使用 SoftHSM 生成令牌和证书时创建的凭据完全匹配。 然后,初始化 UsbPkcs11HsmSigner 对象,将 SoftHSM 库路径、PIN、令牌标签和密钥标签作为参数传递。

此外,创建 PdfSignatureImage 以在文档中添加签名的可视化表示。 最后,调用 SignAndSave 使用 hsmSigner 签署文档并将其保存到指定的输出路径。

HSM 签名代码看起来像什么?

:path=/static-assets/pdf/content-code-examples/how-to/signing-with-hsm.cs
using IronPdf;
using IronPdf.Signing;
using IronSoftware.Pdfium.Signing;
using System.Drawing;

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

// Define Paths and Credentials
string softhsmLibraryPath = @"D:\SoftHSM2\lib\softhsm2-x64.dll";
// These MUST match what you created
string hsmTokenLabel = "MyTestToken";
string hsmPin = "123456";
string hsmKeyLabel = "my-key"; // The label for the key *inside* the token

// Create the HsmSigner object.
UsbPkcs11HsmSigner hsmSigner = new UsbPkcs11HsmSigner(
    softhsmLibraryPath,
    hsmPin,
    hsmTokenLabel,
    hsmKeyLabel
);

// Create the Signature Image
string signatureImagePath = "IronSoftware.png";
PdfSignatureImage sigImage = new PdfSignatureImage(signatureImagePath, 0, new Rectangle(50, 50, 150, 150));

// Sign PDF with HSM
pdf.SignAndSave("signedWithHSM.pdf", hsmSigner);
Imports IronPdf
Imports IronPdf.Signing
Imports IronSoftware.Pdfium.Signing
Imports System.Drawing

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

' Define Paths and Credentials
Dim softhsmLibraryPath As String = "D:\SoftHSM2\lib\softhsm2-x64.dll"
' These MUST match what you created
Dim hsmTokenLabel As String = "MyTestToken"
Dim hsmPin As String = "123456"
Dim hsmKeyLabel As String = "my-key" ' The label for the key *inside* the token

' Create the HsmSigner object.
Dim hsmSigner As New UsbPkcs11HsmSigner(softhsmLibraryPath, hsmPin, hsmTokenLabel, hsmKeyLabel)

' Create the Signature Image
Dim signatureImagePath As String = "IronSoftware.png"
Dim sigImage As New PdfSignatureImage(signatureImagePath, 0, New Rectangle(50, 50, 150, 150))

' Sign PDF with HSM
pdf.SignAndSave("signedWithHSM.pdf", hsmSigner)
$vbLabelText   $csharpLabel

UsbPkcs11HsmSigner 还需要两个可选参数:digestAlgorithmsigningAlgorithm 。 默认情况下,它们设置为SHA256RSA

使用不同的 HSM 配置

不同的 HSM 设备可能需要特定的配置。 下面的示例展示了如何使用自定义算法配置签名器并处理多个签名:

// Configure with custom algorithms
var customHsmSigner = new UsbPkcs11HsmSigner(
    hsmLibraryPath,
    hsmPin,
    hsmTokenLabel,
    hsmKeyLabel,
    digestAlgorithm: IronPdf.Signing.DigestAlgorithm.SHA512,
    signingAlgorithm: IronPdf.Signing.SigningAlgorithm.RSA
);

// Apply signature with custom location and reason
var signatureOptions = new SignatureOptions
{
    SignerName = "Corporate Signing Authority",
    Location = "Company Headquarters",
    Reason = "Contract Approval"
};

// Load existing PDF for signing
var existingPdf = PdfDocument.FromFile("contract.pdf");
existingPdf.SignAndSave("contract-signed.pdf", customHsmSigner, signatureOptions);
// Configure with custom algorithms
var customHsmSigner = new UsbPkcs11HsmSigner(
    hsmLibraryPath,
    hsmPin,
    hsmTokenLabel,
    hsmKeyLabel,
    digestAlgorithm: IronPdf.Signing.DigestAlgorithm.SHA512,
    signingAlgorithm: IronPdf.Signing.SigningAlgorithm.RSA
);

// Apply signature with custom location and reason
var signatureOptions = new SignatureOptions
{
    SignerName = "Corporate Signing Authority",
    Location = "Company Headquarters",
    Reason = "Contract Approval"
};

// Load existing PDF for signing
var existingPdf = PdfDocument.FromFile("contract.pdf");
existingPdf.SignAndSave("contract-signed.pdf", customHsmSigner, signatureOptions);
Imports IronPdf

' Configure with custom algorithms
Dim customHsmSigner As New UsbPkcs11HsmSigner(
    hsmLibraryPath,
    hsmPin,
    hsmTokenLabel,
    hsmKeyLabel,
    digestAlgorithm:=IronPdf.Signing.DigestAlgorithm.SHA512,
    signingAlgorithm:=IronPdf.Signing.SigningAlgorithm.RSA
)

' Apply signature with custom location and reason
Dim signatureOptions As New SignatureOptions With {
    .SignerName = "Corporate Signing Authority",
    .Location = "Company Headquarters",
    .Reason = "Contract Approval"
}

' Load existing PDF for signing
Dim existingPdf As PdfDocument = PdfDocument.FromFile("contract.pdf")
existingPdf.SignAndSave("contract-signed.pdf", customHsmSigner, signatureOptions)
$vbLabelText   $csharpLabel

在处理需要特定合规标准的数字签名示例或需要添加元数据以跟踪签名细节时,这种方法尤其有用。

常见的 HSM 配置问题有哪些?

如果在运行代码示例时遇到以下错误,请按照以下故障排除步骤进行调试和验证您的配置。 有关数字签名问题的其他帮助,请查阅我们的数字签名故障排除指南

当程序找不到 SoftHSM 配置文件,或者 .NET 应用程序以 32 位进程运行而 SoftHSM 库为 64 位时,通常会发生 CKR_GENERAL_ERROR 错误。

PKCS#11 HSM 初始化错误在控制台输出中显示 CHR_GENERAL_ERROR,并带有完整的堆栈跟踪

更改平台目标

导致此错误的一个常见原因是架构不匹配。 您的 C# 应用程序必须作为 64 位进程运行,以匹配 64 位 SoftHSM 库 (softhsm2-x64.dll)。 在 Visual Studio 项目属性中,将平台目标从 "Any CPU "或 "x86 "更改为 x64 以确保兼容性。

Visual Studio 构建配置显示 Platform 目标设置为 x64 架构,并带有条件编译符号

设置环境变量

另一个常见原因是程序无法在 SoftHSM 中找到 .conf 文件。 您必须通过设置系统范围的环境变量来告诉库在哪里查找。 创建一个名为SOFTHSM2_CONF的新变量,并将其值设置为配置文件的完整路径(例如,D:\SoftHSM2\etc\softhsm2.conf)。 更改后,请记住重启 Visual Studio。

Windows 系统变量对话框,突出显示 SOFTISM2_CONF 环境变量,显示 HSM 配置路径

此外,您还可以通过添加这一行来验证变量是否被找到:

Console.WriteLine($"Verifying variable: {Environment.GetEnvironmentVariable("SOFTHSM2_CONF")}");
Console.WriteLine($"Verifying variable: {Environment.GetEnvironmentVariable("SOFTHSM2_CONF")}");
Console.WriteLine($"Verifying variable: {Environment.GetEnvironmentVariable(""SOFTHSM2_CONF"")}")
$vbLabelText   $csharpLabel

如果控制台输出返回空白,说明程序无法找到环境变量。 您必须进行设置,重启 Visual Studio 或计算机,然后重试。

生产 HSM 部署的最佳实践

在生产环境中部署经 HSM 签名的 PDF 时,请考虑这些额外的安全措施:

1.审计日志:对所有 HSM 操作实施全面的日志记录,以保持合规性并跟踪访问情况 2.证书管理:根据组织的安全策略定期更新和轮换证书 3.备份程序:为 HSM 配置建立正确的备份和恢复程序 4.性能优化:监控签名性能并对频繁访问的证书实施缓存策略

这些实践是对标准PDF 签名工作流程的补充,可确保您的文档安全基础架构保持稳健并符合行业标准。

常见问题解答

什么是 HSM 签名,它与普通 PDF 签名有何不同?

IronPDF的HSM(硬件安全模块)签名提供了银行级别的安全性,私钥永远不会离开物理设备。与普通的 .pfx 文件签名不同,HSM 签名将私钥锁定在硬件设备内,无法复制或窃取。

如何在 C# 中为 PDF 配置 HSM 签名?

要使用 IronPDF 配置 HSM 签名,首先使用 "Install-Package IronPdf "通过 NuGet 安装库,然后使用 HSM 凭据(包括库路径、PIN、令牌标签和密钥标签)创建一个 UsbPkcs11HsmSigner 对象。最后,使用 SignAndSave 方法签署 PDF 文档。

使用 HSM 进行 PDF 签名有哪些安全优势?

将 HSM 与 IronPDF 结合使用可提供防篡改数字签名,是关键任务应用的理想选择。这个过程就像把文件带到银行保险库一样--应用程序提供一个 PIN 码,HSM 在内部对文件进行签名,然后返回签名后的文件,而不会暴露私钥,确保文件不会被复制或盗取。

我可以在没有物理设备的情况下测试 HSM 签名吗?

是的,IronPdf 允许您使用 SoftHSM 等库模拟 HSM 签名,用于开发和测试目的。但是,对于生产环境,您必须使用实际的物理 HSM 设备才能确保适当的安全性。

IronPdf 使用什么 API 标准进行 HSM 通信?

IronPDF 使用 PKCS#11 API 标准进行 HSM 通信,确保与标准 HSM 设备兼容。这种通用的 API 使 IronPDF 能够与各种 HSM 硬件令牌和安全模块无缝交互。

如何验证我的 PDF 已成功使用 HSM 签名?

使用 IronPDF 的 HSM 功能签署 PDF 后,您可以在任何标准 PDF 查看器中打开已签署的 PDF 来验证签名。查看器将显示数字签名信息,并确认文档的真实性和完整性。

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。

准备开始了吗?
Nuget 下载 17,386,124 | 版本: 2026.2 刚刚发布