跳至頁尾內容
PDF工具
如何在C#中使用ITextSharp新增數位簽章至PDF

如何將PDF儲存為圖像文件

Full Comparison

Looking for a detailed feature-by-feature breakdown? See how IronPDF stacks up against Itext on pricing, HTML support, and licensing.

View Full Comparison

在我們快速變化的世界中,實體文書很快被電子文件所取代。 無論是簽署合同、核准發票或提交政府表格,數位文件已成為標準。 然而,這種便利帶來了一個新挑戰:確保數位文件的真實性和完整性。

電子簽名提供了解決方案。 不僅僅是在觸摸屏上的隨意塗鴉,數位簽名使用加密技術來驗證簽名者的身份,並確保文件的內容保持不變。 對於C#開發者來說,將此安全層級整合到PDF工作流程中比以往任何時候都更容易,特別是使用如IronPDFiText之類的工具。 在本文中,我們將指導您完成數位簽署PDFs的過程,比較不同的程式庫,提供最佳實踐,並幫助您為下一個專案選擇合適的解決方案。

了解數位簽名

數位簽名是一種加密技術,用於驗證數位訊息或文件的真實性和完整性。 與簡單的圖像簽名或打字名稱不同,數位簽名使用私鑰來加密文件的雜湊值。 這個加密的雜湊值可以被任何人使用簽名者的公鑰進行驗證。

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

  1. 認證 - 簽名驗證來自指定發件人的PDF文件。

  2. 完整性 - 文件自簽署以來未被更改。 即使是微小的變化也會使簽名失效。

數位簽名在許多司法管轄區具有法律約束力,並且在金融、醫療、法律和政府等行業中非常重要。

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

PDF是分發專業文件的標準格式,從法律合同到官方報告。 在PDF中新增數位簽名具有多種關鍵目的:

  • 合法性和合規性:數位簽名符合eIDAS(歐洲)、ESIGN(美國)等法規,使其在法律上被認可。

  • 安全性:簽署的文件不能被更改而不會破壞簽名,以防篡改或欺詐。

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

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

簡而言之,數位簽名為您的文件工作流帶來了信任和效率

比較iText和IronPDF

在C#中實現數位簽名時,兩個程式庫常常脫穎而出:iTextIronPDF。 兩者都是強大的工具,但它們迎合不同型別的開發者和專案需求。 讓我們分解一下它們在真實環境中的使用對比。

iText:力量與複雜性結合

iText在PDF處理領域是個眾所周知的名稱。 它是iText生態系統的一部分,提供了廣泛支持低層次PDF操作的功能,包括加密數位簽名。

需要對簽名外觀、雜湊算法、證書鏈和自訂驗證工作流程進行細粒度控制的開發者將發現iText非常有能力。 它具有高度的擴展能力,設計時考慮到複雜的企業需求。

然而,這種靈活性是有代價的。學習曲線很陡。簡單的任務,例如新增可見簽名,通常需要多個類別、流和配置步驟。 對於新手來說,這可能是令人生畏的。

此外,iText是AGPL許可的,這要求您的應用程式必須是開源的,除非您購買商業授權,對於許多封閉源碼或專有專案來說,這是一個阻礙因素。

IronPDF:簡單與專業的結合

IronPDF,相較之下,採取了一種現代化的、以開發者為先的方式。 它的API設計用來處理常見的PDF任務,例如數位簽名、生成、合併和編輯,設置最小,使其成為.NET框架專案的強大PDF程式庫。

例如,在IronPDF中簽署PDF不需要直接操作流或加密設置。 您只需載入PDF,調用SignPdf(),並傳入您的證書。 它甚至支援附加元資料,如簽名者的位置、原因和聯絡資訊——全部在單個方法調用中實現。

另一個關鍵優勢是授權。 IronPDF提供了一個商業友好授權,沒有AGPL限制,非常適合專業和企業級應用。 儘管它是一個付費產品,但慷慨的免費試用使得在承諾之前進行評估變得容易。

並排摘要

功能 iText IronPDF
易用性 陡峭的學習曲線 對初學者友好,程式碼簡單
授權 AGPL(或商業授權) 商業授權,沒有開源要求
簽名定制 高度可定制的加密控制 簡化的API和可選的元資料字段
文件 詳細但艱澀 清晰的例子和面向開發者的文件
最佳用途 享有深度定制的企業應用 需要快速實現和支援的團隊

iText和IronPDF入門

在深入了解數位簽名實作之前,了解如何使用每個程式庫非常重要。 無論您是在構建一個企業級解決方案還是快速的內部工具,正確的設定可以起決定性作用。

設置iText

iText是強大的基於Java的iText PDF程式庫的.NET移植版。 要開始,您需要通過NuGet安裝它並在專案中引用正確的命名空間。

安裝

您可以輕鬆地通過NuGet包管理控制台將iText程式庫安裝到您的專案中。 你需要做的就是運行以下命令:

Install-Package iTextSharp

安裝iText

這個簡單的安裝確保了這個庫在您的C#專案中的快速實施。

基本設置

一旦安裝完畢,您可以在您的專案中開始使用iText命名空間:

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

請記住,iText是模組化的。 如果您打算使用高級加密功能或時間戳,您可能需要額外的包,例如BouncyCastle.Cryptography。 這可以與iText類似地安裝,只需運行這行:

Install-Package BouncyCastle.Cryptography

需要注意的事項

  • 授權: AGPL授權要求任何使用iText的軟體必須是開源的,除非您購買商業授權。

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

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

如果您願意配置這些積木並需要對簽名過程(例如,設置外觀、驗證級別或時間戳伺服器)進行完全控制,iText是一個堅實的選擇。

設置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. 使用iText和BouncyCastle簽署PDF

包含必要的命名空間

首先,我們需要在程式碼頂部確保有正確使用語句,以存取簽署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

完成文件

最後,我們關閉stamper以完成簽署過程,並將簽署的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

輸出

使用iText簽署的PDF

引導安全配置表單

專業的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");
Imports IronPdf

Dim renderer As New ChromePdfRenderer()

Dim securityConfigForm As String = "
<!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>"

Dim pdf = renderer.RenderHtmlAsPdf(securityConfigForm)
pdf.SaveAs("security-configuration.pdf")
$vbLabelText   $csharpLabel

輸出: 具有Bootstrap 5步驟指示器、表單控制、開關和驗證提醒的專業安全配置表單PDF。 IronPDF以完美的精度渲染了所有表單樣式、實用類別和互動元素,相較於iText的程式化方法展示了卓越的表單渲染能力。

如需有關Bootstrap表單支援的更多詳情,請參閱Bootstrap & Flexbox CSS指南

3. 在C#中使用IronPDF數位簽署PDF

包含必要的命名空間

我們首先導入處理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()。 可選的元資料(聯絡方式、位置、原因)新增了專業性。

  • iText提供了更多控制,但需要詳細設置,包括雜湊算法、流和證書鏈。

總結:只需幾行程式碼,IronPDF就能夠非常輕鬆地使用標準.pfx證書應用數位簽名——無需低層次的加密。 這使得相比於處理類似任務時iText所需的更冗長程式碼更容易實現。

5. 真實世界應用範例

  • 法律團隊:自動簽署從模板生成的合同。

  • 財務:數位簽署發票和報告以防止篡改。

  • 政府門戶:在提交前簽署表格以符合監管標準。

數位簽名的最佳實踐

要在數位簽名實作中獲得最大收益:

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

  • 保持私鑰安全:安全儲存證書,最好是在硬體安全模塊(HSM)中。

  • 為您的簽名加上時間戳:新增可信的時間戳,以確保簽名即使在證書到期後仍然有效。

  • 驗證簽名:在您的應用中包含驗證,以檢測篡改或到期的證書。

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

結論

在PDF文件中新增數位簽名不再是奢侈品——在當今注重安全的數位環境中它是必需品。 無論您是在保護合同、發票、報告或法律文件,具有可信證書支持的具備檢測篡改能力的簽名確保您的文件保持其真實性和完整性。

在本文中,我們探討了兩種強大的PDF簽署方法在C#中的應用:

  • iText,為您提供低層次的加密控制和靈活性,但需要更多的定式程式碼和熟悉BouncyCastle。

  • IronPDF,提供了一個現代化、高層次的API,使得應用安全簽名的過程更加順暢且對開發者友好。

兩個工具都支持安全的.pfx證書,但IronPDF顯然簡化了工作流程—理想物件是想要花更少時間處理加密原語、更多時間交付業務價值的.NET開發者。

iText vs IronPDF對比圖

下一步

如果您還沒有這樣做,請考慮下載IronPDF的免費試用,嘗試僅用幾行程式碼簽署您自己的PDFs。 光是生產力提高就足以值得改變,特別是在時間敏感的專案上工作時。

請注意iText是其各自所有者的註冊商標。 此站點與iText無關,未由其背書或贊助。 所有產品名稱、徽標和品牌均為其各自所有者的財產。 比較僅供資訊參考,並反映了撰寫時的公開可用資訊。

常見問題

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

數位簽章使用加密技術來驗證簽署者的身份並確保文件未被更改。這是通過使用私鑰加密文件的哈希來達到驗證和完整性的目的。

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

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

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

在C#中,您可以使用IronPDF將數位簽章新增到PDF中。該過程涉及載入PDF、使用X509Certificate2提供.pfx證書,並呼叫Sign方法應用簽章。

iTextSharp與其他PDF程式庫在數位簽章方面的主要區別是什麼?

iTextSharp提供對詳細PDF操作的廣泛支持,需要陡峭的學習曲線並需要特定的授權。相比之下,IronPDF適合初學者,具有簡化的API,允許快速實現,且不需要開源授權。

如何在C#中安裝用于簽署文件的PDF程式庫?

您可以通過NuGet使用命令Install-Package IronPdf安裝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擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。

除了開發,Curtis對物聯網(IoT)有濃厚的興趣,探索創新的方法來整合硬體和軟體。在空閒時間,他喜歡玩遊戲和建立Discord機器人,結合他對技術的熱愛與創造力。

Iron 支援團隊

我們線上24小時,每週5天。
聊天
電子郵件
給我打電話