數位簽署PDF文件

查克尼思·賓
查克尼思·賓
2023年1月25日
已更新 2024年12月24日
分享:
This article was translated from English: Does it need improvement?
Translated
View the article in English

重要澄清:簽署PDF文件

開發者常常詢問如何使用IronPDF以程式化的方式在PDF文件上添加簽名。 通常來說,簽名對不同的開發者有不同的意義:

  1. 使用證書數位簽署 PDF 文件以確保其不被更改。

  2. 從圖像檔案將圖形手寫簽名圖像添加到現有的 PDF。

  3. 將證書圖像印在 PDF 上。

  4. 在 PDF 中添加簽名表單欄位,以便某些查看者可以提示簽名。

    開始使用 IronPDF

    立即在您的專案中使用IronPDF,並享受免費試用。

    第一步:
    green arrow pointer


使用數位證書簽署PDF文件

IronPDF 支援多種方法,以 .pfx.p12 格式的數位簽章證書簽署 PDF。 在本指南中,您將了解用於數位簽署 PDF 文件的三種主要方法

Signing MethodDescription
SignSign a PDF with a PdfSignature object
SignWithFileSign PDF with a digital signature certificate(.pfx or .p12) on disk
SignWithStoreSigns the PDF with digital signature extracted from your computer's signature storage. Based on a thumbprint ID

支援的數位簽章證書文件

我們正式遵循X509Certificate2標準,並支持.pfx.p12簽名。 如果您的簽名無法直接應用在IronPDF的簽名方法中,您將需要創建一個X509Certificate2證書,相關說明可在Microsoft文件中找到。

標誌:從 X509Certificate2 創建 PdfSignature

IronPDF 的簽署方法將接受 X509Certificate2 物件,並將 X509KeyStorageFlags 設定為 Exportable

請注意

  • IronPDF 僅支援 X509KeyStorageFlags.Exportable。 一些證書的 KeyStorageFlags 預設設定為可匯出。 嘗試使用不同的 KeyStorageFlags 會導致異常 => Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException:'不支持請求的操作。'

: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")
$vbLabelText   $csharpLabel

在PdfSignature中添加細緻的細節

在實例化 PdfSignature 或其實例化後,可以向 PdfSignature 物件添加有用的資訊,包括日期、簽署聯繫人、位置、簽署原因、時間戳以及將影像作為視覺外觀添加到 PDF 文件中。

提示
支援需要 SHA256 和 SHA512 的時間戳伺服器

: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")
$vbLabelText   $csharpLabel

演示

您可能會看到感嘆號或警告標誌,而不是勾選標記。 這是因為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))
$vbLabelText   $csharpLabel

簽名權限

您可以明確指定您的憑證保持有效的條件。 如果您希望在任何更改後使簽名失效,或只允許表單欄位更改等,請使用下表查看選項:

PdfDocument.SignaturePermissionsDefinition
NoChangesAllowedNo changes are allowed
FormFillingAllowedChanging form field values allowed
FormFillingAndAnnotationsAllowedChanging form field values and modifying annotations allowed

此參數是可選的,若未設置它,將應用一個簽名,該簽名證明特定修訂,且無法撤銷。

保存並簽署 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")
$vbLabelText   $csharpLabel

了解遞增保存簽名的方法

雖然有些瀏覽器如 Chrome 僅顯示一個版本,PDF 文件有能力存儲文檔的先前版本,類似於 Git 提交歷史。 您會在例如Adobe Acrobat這樣的進階PDF檢視器中看到這個功能。

處理PDF簽名時,了解這點非常重要,因為簽名PDF的行為適用於PDF的當前迭代。 您的 PDF 可能包含舊版本的簽名,或可能有一些未簽名的版本。 我們可以將範例如下:

PDF Document IterationCertificate ACertificate BCertificate CCertificate D
0 (first save)
1
2
3
(form field edits only)

(form field edits only)
4 (only form fields edited)
5
(no further edits allowed)

(no further edits allowed)

(no further edits allowed)

以上是經過6個不同版本的文件。 這份文件可能正在公司各部門之間流傳,經過批准後在第三次迭代中被最終確定。在此迭代中,甲方和乙方在設置了「僅限表單字段編輯」權限的情況下簽署了該文件。 這意味著允許在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")
$vbLabelText   $csharpLabel

移除簽名

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()
$vbLabelText   $csharpLabel

驗證PDF中的所有簽名

调用 PDF 文档上的验证签名方法将查看所有文档迭代中的所有签名,并验证它们是否仍然有效。 如果它們都有效,這將返回一個booltrue

: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()
$vbLabelText   $csharpLabel

在 PDF 上蓋章簽名

首先,我將開始簽署一個我想要的PDF文件。 我將使用此示例發票:

我們會將一個手寫簽名(形式為.png圖像)應用到我們的PDF檔。 这可能是手写签名或用于创建证书文件时使用的图像。这是我们将使用的样本签名:

Signature related to 在 PDF 上蓋章簽名

代碼

使用此方法,我們將使用以下代碼將手寫簽名作為水印加蓋到 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")
$vbLabelText   $csharpLabel

輸出結果

在執行此代碼後,我們得到了這個輸出文件,它在右下角帶有我們的簽名:


將未簽名的簽名欄位新增至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")
$vbLabelText   $csharpLabel
未簽名的簽章

您可以在如何建立 PDF 表單文章中閱讀更多關於 IronPDF 及其支援的表單的資訊。

查克尼思·賓
軟體工程師
Chaknith 致力於 IronXL 和 IronBarcode。他在 C# 和 .NET 方面擁有豐富的專業知識,協助改進軟體並支持客戶。他從用戶互動中獲得的洞察力有助於提高產品、文檔和整體體驗。