跳過到頁腳內容
產品比較
如何使用 ITextSharp 在 C# 中為 PDF 新增數位簽名

使用Itextsharp在C#中向PDF添加數字簽名

在今天快速發展的數字世界中,實體文件正在迅速被電子文件取代。 無論是簽署合同、批准發票,還是提交政府表格,數字文檔已成為新常態。 但隨著便利性而來的是一個新的問題:你如何確保這些數字文件的真實性和完整性?

進入電子簽名。 數字簽名不僅僅是一個在觸摸屏上的塗鴉,它利用加密技術來驗證簽署者的身份,並保證文件的內容未被更改。 For C# developers, integrating this level of security into PDF workflows is easier than ever—especially with tools like IronPDF and iTextSharp. 在這篇文章中,我們將介紹 數字簽署 PDF 的過程,對比各個庫,提供最佳實踐,幫助你為下一個項目選擇合適的解決方案。

理解數字簽名

數字簽名是一種加密技術,用於驗證數字消息或文件的真實性和完整性。 與簡單的基於圖像的簽名或打字的名字不同,數字簽名使用私鑰加密文件的哈希值。 然後可以通過使用簽署者的公鑰來驗證這個加密的哈希值。

為什麼這很重要? 因為它確保了兩件事情:

  1. 身份驗證——簽名用於驗證來自所述發件人的 PDF 文件。

  2. 完整性——文件在簽署後未被更改。 即使是微小的更改也會使簽名失效。

數字簽名在許多法域中具有法律效力,並且在例如金融、醫療保健、法律和政府等行業中至關重要。

為什麼在 PDF 中使用數字簽名?

PDF 是從法律合同到官方報告等專業文件的標準格式。 在 PDF 中添加數字簽名可滿足幾個關鍵目的:

  • 合法性和合規:數字簽名符合 eIDAS(歐洲)、ESIGN(美國)等規範,使其具有法律認可。

  • 安全性:簽署的文檔不能在不破壞簽名的情況下被更改,從而防止篡改或欺詐。

  • 效率:無需打印、簽名和掃描。 節省時間並通過安全的數字批准簡化工作流程。

  • 信任:客戶和合作夥伴可以放心地驗證文檔的來源和完整性。

簡而言之,數字簽名為您的文檔工作流程帶來 信任和效率

比較 iTextSharp 和 IronPDF

在 C# 中實施數字簽名時,有兩個庫通常脫穎而出:iTextSharpIronPDF。 這兩者都是強大的工具,但它們迎合不同類型的開發者和項目需求。 讓我們來分解一下它們在實際應用中的比較。

iTextSharp:力量與複雜性

iTextSharp 是 PDF 操作世界中的知名名稱。 它是更大的 iText 7 生態系統的一部分,提供低層次 PDF 操作的廣泛支持,包括加密數字簽名。

需要對簽名外觀、哈希算法、證書鏈和自定義驗證工作流進行 細粒度控制 的開發者會發現 iTextSharp 非常有能力。 它高度可擴展,專為複雜的企業需求設計。

但是,這種靈活性是有代價的。學習曲線非常陡峭。簡單的任務,如添加顯示的簽名,通常需要多個類、流和配置步驟。 對於新用戶來說,這可能難以承受。

此外,iTextSharp 在 AGPL 授權下,其要求您的應用程序是開源的,除非您購買商業許可證—這對於許多閉源或專有項目來說是一個不可接受的條件。

IronPDF:簡單與專業的結合

IronPDF,對比之下,採取了一種現代、以開發者為中心的方法。 其 API 設計用於以最少的設置處理常見的 PDF 任務,比如數字簽名、生成、合併和編輯,這使其成為 .NET 框架項目的強大 PDF 庫。

例如,在 IronPDF 中簽署 PDF 不需要直接處理流或加密設置。 您只需加載 PDF,調用 SignPdf(),並傳入您的證書。 它甚至支持附加元數據,如簽名者位置、原因和聯繫信息——僅在一個方法調用中完成。

另一個主要優勢是授權。 IronPDF 提供一個具有友好的商業許可證,沒有 AGPL 限制,這對於專業和企業級應用程序而言是理想的。 雖然它是一個付費產品,但慷慨的免費試用使其在承諾之前易於評估。

並排總結

功能 iTextSharp IronPDF
易用性 陡峭的學習曲線 初學者友好,最小代碼
授權 AGPL(或需付費的商業許可證) 無開源需求的商業許可證
簽名自定義 高度可自定義帶有加密控制 簡化的 API,帶有可選的元數據字段
文檔 詳細但密集 清晰的範例,面向開發者的文檔
最佳用途 需要深入自定義的企業應用程序 需要快速實施和支持的團隊

入門 iTextSharp 和 IronPDF

在深入研究數字簽名實現之前,非常重要的是理解如何使用每個庫進行啟用。 無論您是要構建企業級解決方案還是快速的內部工具,正確的設置可以帶來完全不同的結果。

設置 iTextSharp

iTextSharp 是強大的基於 Java 的 iText PDF 庫的 .NET 版本。 要開始使用,您需要通過 NuGet 安裝它並在項目中引用正確的命名空間。

安裝

您可以輕鬆地通過 NuGet 套件管理控制台將 iTextSharp 庫安裝到您的項目中。 您只需運行以下命令:

Install-Package iTextSharp

安裝 iTextSharp

這種便捷的安裝確保快速實施此庫於您的 C# 項目中。

基本設置

安裝後,您可以在項目中開始使用 iTextSharp 命名空間:

using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
Imports iTextSharp.text.pdf
Imports iTextSharp.text.pdf.security
$vbLabelText   $csharpLabel

請記住 iTextSharp 是模塊化的。 如果您打算使用高級加密功能或時間戳,您可能需要額外的包如 BouncyCastle.Cryptography。 可以像安裝 iTextSharp 一樣安裝,僅需運行這行:

Install-Package BouncyCastle.Cryptography

需要留意的事情

  • 授權:AGPL 授權要求任何使用 iTextSharp 的軟件是開源的,除非購買商業授權。

  • 依賴項:加密操作通常需要 BouncyCastle 來處理證書。

  • 學習曲線:即使是基本的簽名也涉及理解 PdfSignerIExternalSignature 和各種加密提供程序。

如果您能夠自如配置這些構件,並需要對簽名過程進行完全控制(例如設置外觀、驗證級別或時間戳伺服器),iTextSharp 是一個穩妥的選擇。

設置 IronPDF

IronPDF 是一個以提高開發者效率為目的建造的商業 PDF 庫。 這是為那些想要通過最少麻煩生成、編輯和簽署 PDF 的 .NET 開發者設計的。 IronPDF 提供一個相當順暢的上手體驗,尤其是對那些重視干淨的 API 和快速結果的用戶而言。

安裝

通過 NuGet 安裝最新的 IronPDF 包:

Install-Package IronPdf

通過 NuGet 主控台安裝 IronPDF

或使用 .NET CLI:

Install-Package IronPdf

基本設置

首先導入主要的 IronPDF 命名空間:

using IronPdf;
using IronPdf;
Imports IronPdf
$vbLabelText   $csharpLabel

就是這樣——你準備好加載一個 PDF 並開始添加數字簽名。

IronPDF 內部管理一切:證書加載、可見簽名定位、元數據和最終導出。 您不必手動管理 PDF 流或加密算法,這對於快速開發是一個巨大的優勢。

對初學者的關鍵優點

  • 一體化:不需要額外的依賴項或加密庫。

  • 無 AGPL 顧慮:IronPDF 提供永久性授權和慷慨的免費試用。

  • 可視化渲染:IronPDF 精確渲染 PDF,使其正如被打印時看起來相同,非常適合合約和官方文件。

分步操作:添加數字簽名

1. 準備您的證書

您需要一個 .pfx 數字證書文件和一個 密碼。 這些用於生成數字簽名。 您可以從受信任的證書機構 (CA) 獲取證書,或使用 OpenSSL 等工具生成一個用於內部用途。

2. 使用 iTextSharp 和 BouncyCastle 進行 PDF 簽名

包括必要的命名空間

首先,我們需要確保在代碼頂部使用正確的語句,以便訪問用 iTextSharp 進行 PDF 數字簽名所需的各種類和方法。

using System;
using System.IO;
using System.Linq;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Pkcs;
using System;
using System.IO;
using System.Linq;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Pkcs;
Imports System
Imports System.IO
Imports System.Linq
Imports iTextSharp.text.pdf
Imports iTextSharp.text.pdf.security
Imports Org.BouncyCastle.Crypto
Imports Org.BouncyCastle.Pkcs
$vbLabelText   $csharpLabel

定義輸入 PDF 並將其加載到 PdfReader

接下來我們指定現有 PDF 的路徑並將其加載到 PdfReader 中。 我們還會分配一些字符串變量,這些變量會在後面的代碼中使用。

// Path to the unsigned PDF you want to sign
string filename = "example.pdf";

// Load the existing PDF into a reader
PdfReader pdfReader = new PdfReader(filename);

string reason = "Digital Signature Reason";
string location = "Digital Signature Location";
// Path to the unsigned PDF you want to sign
string filename = "example.pdf";

// Load the existing PDF into a reader
PdfReader pdfReader = new PdfReader(filename);

string reason = "Digital Signature Reason";
string location = "Digital Signature Location";
' Path to the unsigned PDF you want to sign
Dim filename As String = "example.pdf"

' Load the existing PDF into a reader
Dim pdfReader As New PdfReader(filename)

Dim reason As String = "Digital Signature Reason"
Dim location As String = "Digital Signature Location"
$vbLabelText   $csharpLabel

定義證書路徑和密碼

接下來,我們指出 .pfx 證書文件並提供用於保護它的密碼。

// Path to your .pfx certificate file (must contain private key)
string pfxFilePath = "certificate-file.pfx";

// Password for the certificate (make sure to protect this securely!)
string pfxPassword = "Password";
// Path to your .pfx certificate file (must contain private key)
string pfxFilePath = "certificate-file.pfx";

// Password for the certificate (make sure to protect this securely!)
string pfxPassword = "Password";
' Path to your .pfx certificate file (must contain private key)
Dim pfxFilePath As String = "certificate-file.pfx"

' Password for the certificate (make sure to protect this securely!)
Dim pfxPassword As String = "Password"
$vbLabelText   $csharpLabel

使用 Pkcs12Store 加載 .PFX 證書

我們使用 BouncyCastle 將證書和私鑰加載到一個安全的存儲中。

// Initialize a new PKCS#12 key store (used for handling the PFX certificate)
Pkcs12StoreBuilder pkcs12StoreBuilder = new Pkcs12StoreBuilder();
Pkcs12Store pfxKeyStore = pkcs12StoreBuilder.Build();

// Load the certificate and private key from the PFX file
using (FileStream pfxStream = new FileStream(pfxFilePath, FileMode.Open, FileAccess.Read))
{
    // Load into the key store using the provided password
    pfxKeyStore.Load(pfxStream, pfxPassword.ToCharArray());
}
// Initialize a new PKCS#12 key store (used for handling the PFX certificate)
Pkcs12StoreBuilder pkcs12StoreBuilder = new Pkcs12StoreBuilder();
Pkcs12Store pfxKeyStore = pkcs12StoreBuilder.Build();

// Load the certificate and private key from the PFX file
using (FileStream pfxStream = new FileStream(pfxFilePath, FileMode.Open, FileAccess.Read))
{
    // Load into the key store using the provided password
    pfxKeyStore.Load(pfxStream, pfxPassword.ToCharArray());
}
' Initialize a new PKCS#12 key store (used for handling the PFX certificate)
Dim pkcs12StoreBuilder As New Pkcs12StoreBuilder()
Dim pfxKeyStore As Pkcs12Store = pkcs12StoreBuilder.Build()

' Load the certificate and private key from the PFX file
Using pfxStream As New FileStream(pfxFilePath, FileMode.Open, FileAccess.Read)
	' Load into the key store using the provided password
	pfxKeyStore.Load(pfxStream, pfxPassword.ToCharArray())
End Using
$vbLabelText   $csharpLabel

準備 PdfStamper 以添加簽名

PdfStamper 讓我們能夠在保持原始內容的同時應用數字簽名。

// Create a PdfStamper that enables signing and appends the signature to the document
PdfStamper pdfStamper = PdfStamper.CreateSignature(
    pdfReader,
    new FileStream("MyPDF_Signed.pdf", FileMode.Create), // Output path
    '\0',                                                // PDF version (unchanged)
    null,                                                // Temp file path (optional)
    true                                                 // Append mode (preserves original content)
);
// Create a PdfStamper that enables signing and appends the signature to the document
PdfStamper pdfStamper = PdfStamper.CreateSignature(
    pdfReader,
    new FileStream("MyPDF_Signed.pdf", FileMode.Create), // Output path
    '\0',                                                // PDF version (unchanged)
    null,                                                // Temp file path (optional)
    true                                                 // Append mode (preserves original content)
);
Imports Microsoft.VisualBasic

' Create a PdfStamper that enables signing and appends the signature to the document
Dim pdfStamper As PdfStamper = PdfStamper.CreateSignature(pdfReader, New FileStream("MyPDF_Signed.pdf", FileMode.Create), ControlChars.NullChar, Nothing, True)
$vbLabelText   $csharpLabel

自定義簽名外觀

現在我們定義簽名將如何以及在文件中視覺上顯示的位置。

// Access the signature appearance settings
PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance;

// Add optional metadata (shows up in PDF signature details)
signatureAppearance.Reason = reason;
signatureAppearance.Location = location;

// Position the visible signature on the page (x, y, width, height in points)
float x = 360;
float y = 130;
signatureAppearance.Acro6Layers = false;              // Use compact signature appearance
signatureAppearance.Layer4Text = PdfSignatureAppearance.QuestionMark; // Custom label text
signatureAppearance.SetVisibleSignature(
    new iTextSharp.text.Rectangle(x, y, x + 150, y + 50), // Rectangle position
    1,                                                    // Page number
    "signature"                                           // Field name
);
// Access the signature appearance settings
PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance;

// Add optional metadata (shows up in PDF signature details)
signatureAppearance.Reason = reason;
signatureAppearance.Location = location;

// Position the visible signature on the page (x, y, width, height in points)
float x = 360;
float y = 130;
signatureAppearance.Acro6Layers = false;              // Use compact signature appearance
signatureAppearance.Layer4Text = PdfSignatureAppearance.QuestionMark; // Custom label text
signatureAppearance.SetVisibleSignature(
    new iTextSharp.text.Rectangle(x, y, x + 150, y + 50), // Rectangle position
    1,                                                    // Page number
    "signature"                                           // Field name
);
' Access the signature appearance settings
Dim signatureAppearance As PdfSignatureAppearance = pdfStamper.SignatureAppearance

' Add optional metadata (shows up in PDF signature details)
signatureAppearance.Reason = reason
signatureAppearance.Location = location

' Position the visible signature on the page (x, y, width, height in points)
Dim x As Single = 360
Dim y As Single = 130
signatureAppearance.Acro6Layers = False ' Use compact signature appearance
signatureAppearance.Layer4Text = PdfSignatureAppearance.QuestionMark ' Custom label text
signatureAppearance.SetVisibleSignature(New iTextSharp.text.Rectangle(x, y, x + 150, y + 50), 1, "signature")
$vbLabelText   $csharpLabel

提取私鑰並簽署PDF

我們檢索包含私鑰的證書條目別名(名稱)。 如果別名存在,我們繼續使用 SHA-256 生成並嵌入數字簽名。

// Find the first alias in the PFX that has a private key entry
string alias = pfxKeyStore.Aliases.Cast<string>().FirstOrDefault(
    entryAlias => pfxKeyStore.IsKeyEntry(entryAlias)
);

// Ensure a valid alias (certificate) was found
if (alias != null)
{
    // Retrieve the private key for signing
    ICipherParameters privateKey = pfxKeyStore.GetKey(alias).Key;

    // Create a signer using SHA-256 and the private key
    IExternalSignature pks = new PrivateKeySignature(privateKey, DigestAlgorithms.SHA256);

    // Perform the digital signing operation using CMS format
    MakeSignature.SignDetached(
        signatureAppearance,     // Signature appearance
        pks,                     // External signature handler
        new Org.BouncyCastle.X509.X509Certificate[] {
            pfxKeyStore.GetCertificate(alias).Certificate
        },                       // Certificate chain (basic single-cert example)
        null, null, null,        // Optional CRL, OCSP, TSA
        0,                       // Estimated size for the signature (0 = auto)
        CryptoStandard.CMS       // Signature standard (CMS vs CAdES)
    );
}
else
{
    Console.WriteLine("Private key not found in the PFX certificate.");
}
// Find the first alias in the PFX that has a private key entry
string alias = pfxKeyStore.Aliases.Cast<string>().FirstOrDefault(
    entryAlias => pfxKeyStore.IsKeyEntry(entryAlias)
);

// Ensure a valid alias (certificate) was found
if (alias != null)
{
    // Retrieve the private key for signing
    ICipherParameters privateKey = pfxKeyStore.GetKey(alias).Key;

    // Create a signer using SHA-256 and the private key
    IExternalSignature pks = new PrivateKeySignature(privateKey, DigestAlgorithms.SHA256);

    // Perform the digital signing operation using CMS format
    MakeSignature.SignDetached(
        signatureAppearance,     // Signature appearance
        pks,                     // External signature handler
        new Org.BouncyCastle.X509.X509Certificate[] {
            pfxKeyStore.GetCertificate(alias).Certificate
        },                       // Certificate chain (basic single-cert example)
        null, null, null,        // Optional CRL, OCSP, TSA
        0,                       // Estimated size for the signature (0 = auto)
        CryptoStandard.CMS       // Signature standard (CMS vs CAdES)
    );
}
else
{
    Console.WriteLine("Private key not found in the PFX certificate.");
}
' Find the first alias in the PFX that has a private key entry
Dim [alias] As String = pfxKeyStore.Aliases.Cast(Of String)().FirstOrDefault(Function(entryAlias) pfxKeyStore.IsKeyEntry(entryAlias))

' Ensure a valid alias (certificate) was found
If [alias] IsNot Nothing Then
	' Retrieve the private key for signing
	Dim privateKey As ICipherParameters = pfxKeyStore.GetKey([alias]).Key

	' Create a signer using SHA-256 and the private key
	Dim pks As IExternalSignature = New PrivateKeySignature(privateKey, DigestAlgorithms.SHA256)

	' Perform the digital signing operation using CMS format
	MakeSignature.SignDetached(signatureAppearance, pks, New Org.BouncyCastle.X509.X509Certificate() { pfxKeyStore.GetCertificate([alias]).Certificate }, Nothing, Nothing, Nothing, 0, CryptoStandard.CMS)
Else
	Console.WriteLine("Private key not found in the PFX certificate.")
End If
$vbLabelText   $csharpLabel

完成文檔

最後,我們關閉印章以完成簽名過程並將簽名的 PDF 寫入磁盤。

// Close the stamper to save and finalize the signed PDF
pdfStamper.Close();
// Close the stamper to save and finalize the signed PDF
pdfStamper.Close();
' Close the stamper to save and finalize the signed PDF
pdfStamper.Close()
$vbLabelText   $csharpLabel

輸出

使用 iTextSharp 簽名的 PDF

Bootstrap 安全配置表單

專業的 PDF 安全性需要直觀的配置接口。 此 Bootstrap 5 示例演示了 IronPDF 渲染多步安全配置表單,具有驗證狀態和進度跟蹤的能力。

using IronPdf;

var renderer = new ChromePdfRenderer();

string securityConfigForm = @"
<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css' rel='stylesheet'>
    <style>
        .step-indicator { display: flex; justify-content: space-between; margin-bottom: 30px; }
        .step { flex: 1; text-align: center; position: relative; }
        .step-number { width: 40px; height: 40px; border-radius: 50%; background: #e9ecef;
            display: inline-flex; align-items: center; justify-content: center; font-weight: 700; }
        .step.completed .step-number { background: #198754; color: white; }
        .step.active .step-number { background: #0d6efd; color: white; }
        @media print { .form-section { page-break-inside: avoid; } }
    </style>
</head>
<body class='bg-light'>
    <div class='container py-4'>
        <div class='row justify-content-center'>
            <div class='col-lg-8'>
                <h2 class='text-center mb-4'>PDF Security Configuration</h2>

                <div class='step-indicator mb-4'>
                    <div class='step completed'>
                        <div class='step-number'>✓</div>
                        <div class='small mt-2'>Certificate</div>
                    </div>
                    <div class='step completed'>
                        <div class='step-number'>✓</div>
                        <div class='small mt-2'>Signature</div>
                    </div>
                    <div class='step active'>
                        <div class='step-number'>3</div>
                        <div class='small mt-2'>Encryption</div>
                    </div>
                    <div class='step'>
                        <div class='step-number'>4</div>
                        <div class='small mt-2'>Finalize</div>
                    </div>
                </div>

                <div class='card shadow-sm form-section'>
                    <div class='card-header bg-primary text-white'>
                        <h5 class='mb-0'>Step 3: Encryption & Permissions</h5>
                    </div>
                    <div class='card-body'>
                        <div class='mb-3'>
                            <label class='form-label'><strong>Encryption Level</strong></label>
                            <select class='form-select'>
                                <option>AES 128-bit</option>
                                <option selected>AES 256-bit (Recommended)</option>
                                <option>RC4 128-bit (Legacy)</option>
                            </select>
                            <small class='text-muted'>AES-256 provides enterprise-grade security</small>
                        </div>

                        <div class='mb-3'>
                            <label class='form-label'><strong>Document Permissions</strong></label>
                            <div class='form-check form-switch'>
                                <input class='form-check-input' type='checkbox' id='allowPrint' checked>
                                <label class='form-check-label' for='allowPrint'>Allow Printing</label>
                            </div>
                            <div class='form-check form-switch'>
                                <input class='form-check-input' type='checkbox' id='allowCopy'>
                                <label class='form-check-label' for='allowCopy'>Allow Content Copying</label>
                            </div>
                            <div class='form-check form-switch'>
                                <input class='form-check-input' type='checkbox' id='allowModify'>
                                <label class='form-check-label' for='allowModify'>Allow Document Modification</label>
                            </div>
                            <div class='form-check form-switch'>
                                <input class='form-check-input' type='checkbox' id='allowAnnotate' checked>
                                <label class='form-check-label' for='allowAnnotate'>Allow Annotations</label>
                            </div>
                        </div>

                        <div class='mb-3'>
                            <label class='form-label'><strong>Password Protection</strong></label>
                            <input type='password' class='form-control mb-2' placeholder='Owner Password' value='••••••••'>
                            <input type='password' class='form-control' placeholder='User Password (Optional)'>
                            <small class='text-muted'>Owner password controls document permissions</small>
                        </div>

                        <div class='alert alert-success'>
                            <strong>✓ Configuration Valid</strong><br>
                            <small>Security settings meet compliance requirements</small>
                        </div>
                    </div>
                    <div class='card-footer'>
                        <div class='d-flex justify-content-between'>
                            <button class='btn btn-outline-secondary'>← Previous</button>
                            <button class='btn btn-primary'>Continue →</button>
                        </div>
                    </div>
                </div>

                <div class='card mt-3 shadow-sm'>
                    <div class='card-body'>
                        <h6 class='text-primary'>Security Comparison</h6>
                        <div class='row g-2'>
                            <div class='col-6'>
                                <div class='text-center p-2 bg-success text-white rounded'>
                                    <strong>IronPDF</strong><br>
                                    <small>AES-256 Native</small>
                                </div>
                            </div>
                            <div class='col-6'>
                                <div class='text-center p-2 bg-warning text-dark rounded'>
                                    <strong>iTextSharp</strong><br>
                                    <small>Complex Setup</small>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>";

var pdf = renderer.RenderHtmlAsPdf(securityConfigForm);
pdf.SaveAs("security-configuration.pdf");
using IronPdf;

var renderer = new ChromePdfRenderer();

string securityConfigForm = @"
<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css' rel='stylesheet'>
    <style>
        .step-indicator { display: flex; justify-content: space-between; margin-bottom: 30px; }
        .step { flex: 1; text-align: center; position: relative; }
        .step-number { width: 40px; height: 40px; border-radius: 50%; background: #e9ecef;
            display: inline-flex; align-items: center; justify-content: center; font-weight: 700; }
        .step.completed .step-number { background: #198754; color: white; }
        .step.active .step-number { background: #0d6efd; color: white; }
        @media print { .form-section { page-break-inside: avoid; } }
    </style>
</head>
<body class='bg-light'>
    <div class='container py-4'>
        <div class='row justify-content-center'>
            <div class='col-lg-8'>
                <h2 class='text-center mb-4'>PDF Security Configuration</h2>

                <div class='step-indicator mb-4'>
                    <div class='step completed'>
                        <div class='step-number'>✓</div>
                        <div class='small mt-2'>Certificate</div>
                    </div>
                    <div class='step completed'>
                        <div class='step-number'>✓</div>
                        <div class='small mt-2'>Signature</div>
                    </div>
                    <div class='step active'>
                        <div class='step-number'>3</div>
                        <div class='small mt-2'>Encryption</div>
                    </div>
                    <div class='step'>
                        <div class='step-number'>4</div>
                        <div class='small mt-2'>Finalize</div>
                    </div>
                </div>

                <div class='card shadow-sm form-section'>
                    <div class='card-header bg-primary text-white'>
                        <h5 class='mb-0'>Step 3: Encryption & Permissions</h5>
                    </div>
                    <div class='card-body'>
                        <div class='mb-3'>
                            <label class='form-label'><strong>Encryption Level</strong></label>
                            <select class='form-select'>
                                <option>AES 128-bit</option>
                                <option selected>AES 256-bit (Recommended)</option>
                                <option>RC4 128-bit (Legacy)</option>
                            </select>
                            <small class='text-muted'>AES-256 provides enterprise-grade security</small>
                        </div>

                        <div class='mb-3'>
                            <label class='form-label'><strong>Document Permissions</strong></label>
                            <div class='form-check form-switch'>
                                <input class='form-check-input' type='checkbox' id='allowPrint' checked>
                                <label class='form-check-label' for='allowPrint'>Allow Printing</label>
                            </div>
                            <div class='form-check form-switch'>
                                <input class='form-check-input' type='checkbox' id='allowCopy'>
                                <label class='form-check-label' for='allowCopy'>Allow Content Copying</label>
                            </div>
                            <div class='form-check form-switch'>
                                <input class='form-check-input' type='checkbox' id='allowModify'>
                                <label class='form-check-label' for='allowModify'>Allow Document Modification</label>
                            </div>
                            <div class='form-check form-switch'>
                                <input class='form-check-input' type='checkbox' id='allowAnnotate' checked>
                                <label class='form-check-label' for='allowAnnotate'>Allow Annotations</label>
                            </div>
                        </div>

                        <div class='mb-3'>
                            <label class='form-label'><strong>Password Protection</strong></label>
                            <input type='password' class='form-control mb-2' placeholder='Owner Password' value='••••••••'>
                            <input type='password' class='form-control' placeholder='User Password (Optional)'>
                            <small class='text-muted'>Owner password controls document permissions</small>
                        </div>

                        <div class='alert alert-success'>
                            <strong>✓ Configuration Valid</strong><br>
                            <small>Security settings meet compliance requirements</small>
                        </div>
                    </div>
                    <div class='card-footer'>
                        <div class='d-flex justify-content-between'>
                            <button class='btn btn-outline-secondary'>← Previous</button>
                            <button class='btn btn-primary'>Continue →</button>
                        </div>
                    </div>
                </div>

                <div class='card mt-3 shadow-sm'>
                    <div class='card-body'>
                        <h6 class='text-primary'>Security Comparison</h6>
                        <div class='row g-2'>
                            <div class='col-6'>
                                <div class='text-center p-2 bg-success text-white rounded'>
                                    <strong>IronPDF</strong><br>
                                    <small>AES-256 Native</small>
                                </div>
                            </div>
                            <div class='col-6'>
                                <div class='text-center p-2 bg-warning text-dark rounded'>
                                    <strong>iTextSharp</strong><br>
                                    <small>Complex Setup</small>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>";

var pdf = renderer.RenderHtmlAsPdf(securityConfigForm);
pdf.SaveAs("security-configuration.pdf");
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

輸出:專業的安全配置表單 PDF,包含 Bootstrap 5 步驟指示器、表單控制、開關和驗證警示。 IronPDF 完美渲染所有表單樣式、實用程序類和互動元素,展示了其優於 iTextSharp 程序化方式的優越表單渲染能力。

如需有關 Bootstrap 表單支持的更多詳細信息,請參閱 Bootstrap 與 Flexbox CSS 指南

3. 在 C# 中使用 IronPDF 進行數字簽名

包括必要的命名空間

首先,我們通過導入所需的命名空間為 pdf 簽名、證書處理和圖像定位進行導入。

using IronPdf;
using IronPdf.Signing;
using IronSoftware.Drawing;
using System.Security.Cryptography.X509Certificates;
using IronPdf;
using IronPdf.Signing;
using IronSoftware.Drawing;
using System.Security.Cryptography.X509Certificates;
Imports IronPdf
Imports IronPdf.Signing
Imports IronSoftware.Drawing
Imports System.Security.Cryptography.X509Certificates
$vbLabelText   $csharpLabel

加載您想要簽名的 PDF

我們使用 IronPDF 的簡單 PdfDocument API 從磁碟中加載現有的 PDF 文件。 您還可以為此任務創建新的 PDF 文件。

var pdf = PdfDocument.FromFile("example.pdf");
var pdf = PdfDocument.FromFile("example.pdf");
Dim pdf = PdfDocument.FromFile("example.pdf")
$vbLabelText   $csharpLabel

加載用於簽名的 PFX 證書

我們加載包含私鑰的 .pfx 證書。 需要設置 Exportable 標誌以便可以訪問簽署密鑰。

X509Certificate2 cert = new X509Certificate2(
    "IronSoftware.pfx",
    "Password",
    X509KeyStorageFlags.Exportable
);
X509Certificate2 cert = new X509Certificate2(
    "IronSoftware.pfx",
    "Password",
    X509KeyStorageFlags.Exportable
);
Dim cert As New X509Certificate2("IronSoftware.pfx", "Password", X509KeyStorageFlags.Exportable)
$vbLabelText   $csharpLabel

使用證書創建新的 PdfSignature

我們從加載的證書中創建一個新的 PdfSignature 對象。

var sig = new PdfSignature(cert);
var sig = new PdfSignature(cert);
Dim sig = New PdfSignature(cert)
$vbLabelText   $csharpLabel

應用簽名並保存輸出

我們對 PDF 進行數字簽名並將簽名的 PDF 文檔另存為新文件。

pdf.Sign(sig);
pdf.SaveAs("signed.pdf");
pdf.Sign(sig);
pdf.SaveAs("signed.pdf");
pdf.Sign(sig)
pdf.SaveAs("signed.pdf")
$vbLabelText   $csharpLabel

輸出

使用 IronPDF 簽名的 PDF

4. 代碼解釋

  • IronPDF 保持簽名過程簡單且可讀。 只需加載 PDF,提供證書,然後調用 SignPdf()。 可選的元數據(聯繫方式、地點、原因)增加了專業性。

  • iTextSharp 提供了更多控制,但需要詳細的設置,涉及哈希算法、流和證書鏈。

總結:通過幾行代碼,IronPDF 讓使用標準 .pfx 證書應用數字簽名變得非常簡單 — 無需低層次的加密。 相比需要如 iTextSharp 類庫那樣更長代碼來處理同樣的任務,這使得它易於實施。

5. 實際應用案例

  • 法律團隊:合同自動化生成時,立即簽署。

  • 金融:數字簽署發票和報告以防止篡改。

  • 政府門戶:在表單提交之前簽署表單以符合法規標準。

數字簽名的最佳實踐

要最大限度地發揮您的數字簽名實現的作用:

  • 使用強力證書:選擇 2048 位 RSA 密鑰或更強。

  • 保持私鑰安全:將證書安全地存儲,理想情況下放在硬件安全模塊 (HSM) 中。

  • 對您的簽名加上時間戳:添加受信任的時間戳以確保在證書過期後簽名仍然有效。

  • 驗證簽名:在您的應用程序中包括驗證以檢測篡改或過期的證書。

  • 自動化:在您的部署管道中安排簽名操作以保證文件的一致完整性。

結論

將數字簽名添加到 PDF 文件中不再是一種奢侈品——在今天的注重安全的數字環境中,它已成為必要的。 無論您是保護合同、發票、報告還是法律文件,擁有一個受信任的證書支持的防篡改簽名能夠確保您的文件保持其真實性和完整性。

在這篇文章中,我們探討了在 C# 中實現 PDF 簽名的兩種強大方法:

  • iTextSharp,它給予您低層次的加密控制和靈活性,但需要更多樣板和對 BouncyCastle 的熟悉。

  • IronPDF,它提供一個現代的高級 API,使應用安全簽名的過程變得無縫且對開發者友好。

這兩個工具都支持安全的 .pfx 證書,但 IronPDF 顯然簡化了工作流程——這對希望花更少時間處理加密原件、而更多時間交付業務價值的 .NET 開發人員來說尤其理想。

iTextSharp vs IronPDF 比較圖表

下一步

如果您還沒試過,可以考慮下載一個 IronPDF 的免費試用版 試試僅用幾行代碼簽署您自己的 PDF。 尤其是在處理有時間限制的項目時,生產力提升本身就足以值得轉換。

請注意iTextSharp 是其各自所有者的註冊商標。 本網站未被 iTextSharp 授權、贊助或認可。所有產品名稱、商標和品牌均為其各自所有者的財產。 比較僅供信息參考,並反映撰寫時公開可用的信息。

常見問題解答

數位簽章如何確保PDF文件的真實性?

數位簽章利用加密技術來驗證簽署者的身份,並確保文件未被竄改。其原理是使用私鑰對文件的雜湊值進行加密,從而同時提供身份驗證和完整性保障。

為什麼數位簽章對電子文檔很重要?

數位簽章對於維護電子文件的合法性、安全性、效率和可信度至關重要。它們確保符合法規要求,防止篡改,簡化文件工作流程,並確認文件的來源和完整性。

如何在 C# 中為 PDF 新增數位簽章?

在 C# 中,可以使用 IronPDF 為 PDF 新增數位簽章。過程包括載入 PDF 文件,使用X509Certificate2提供 .pfx 證書,然後呼叫Sign方法來套用簽章。

iTextSharp 與其他用於數位簽章的 PDF 函式庫的主要差異是什麼?

iTextSharp 提供對複雜 PDF 操作的全面支持,但學習曲線陡峭,且需要特定許可證。相比之下,IronPDF 對初學者友好,API 簡化,易於快速部署,且無需開源許可證。

如何在C#中安裝用於文件簽章的PDF庫?

您可以使用 NuGet 指令安裝 IronPDF: Install-Package IronPdf ,或使用 .NET CLI 的dotnet add package IronPdf

使用 iTextSharp 對 PDF 檔案進行數位簽章需要哪些步驟?

要使用 iTextSharp 對 PDF 進行數位簽名,您需要配置PdfStamper ,自訂簽名外觀,使用 BouncyCastle 載入 .pfx 證書,並使用PdfSignerIExternalSignature進行加密操作。

在PDF中實施數位簽章有哪些最佳實務?

最佳實踐包括使用強證書、保護私鑰、在簽名中添加時間戳記、定期驗證簽名以及自動化簽名過程以維護文件完整性。

數位簽章在PDF文件中有哪些實際應用?

數位簽名通常用於法律部門簽署合約、財務部門批准發票和報告,以及政府機構處理表格以確保符合監管標準。

對於需要快速實現數位簽章的開發人員來說,哪個 PDF 庫更好?

對於尋求快速實現數位簽章的開發人員來說,IronPDF 是一個不錯的選擇,因為它具有簡單明了的 API,可以簡化簽名過程,並且只需要極少的程式碼。

IronPDF 是否相容於 .NET 10,可用於新增和驗證數位簽章?

是的-IronPDF 與 .NET 10 完全相容。它支援 .NET 10(以及 .NET 9、8、7 等),其數位簽章功能(例如使用PdfSignatureX509Certificate2 、簽章和驗證)在 .NET 10 執行階段中開箱即用。

Curtis Chau
技術作家

Curtis Chau 擁有卡爾頓大學計算機科學學士學位,專注於前端開發,擅長於 Node.js、TypeScript、JavaScript 和 React。Curtis 熱衷於創建直觀且美觀的用戶界面,喜歡使用現代框架並打造結構良好、視覺吸引人的手冊。

除了開發之外,Curtis 對物聯網 (IoT) 有著濃厚的興趣,探索將硬體和軟體結合的創新方式。在閒暇時間,他喜愛遊戲並構建 Discord 機器人,結合科技與創意的樂趣。