如何在 Java 中使用 GroupDocs 簽署 PDF

介紹

如果您需要在 Java 應用程式中以程式方式 how to sign pdf 檔案,您來對地方了。想像一個企業合約管理系統,必須在每份 PDF 送交客戶前附加具法律效力的簽章。若沒有可靠的簽署解決方案,您將面臨不合規、被竄改以及無止盡的手動工作風險。

在本教學中,您將學會如何使用 GroupDocs.Signature 在 Java 中為 PDF 檔案加入數位簽章。我們會涵蓋從環境設定到自訂可見簽章外觀、處理大型文件以及套用生產等級安全實踐的全部內容。

完成本指南後,您將能夠:

  • 安裝與設定 GroupDocs.Signature for Java。
  • 初始化 Signature 物件並載入 PDF。
  • 使用 .pfx 憑證配置 DigitalSignOptions。
  • 自訂簽章的外觀、位置與邊框。
  • 簽署文件、驗證結果,並處理常見陷阱。

讓我們開始,讓您的 PDF 防止被竄改。

快速回答

  • 哪個函式庫可以在 Java 中簽署 PDF? GroupDocs.Signature for Java。
  • 需要哪種憑證格式? PKCS#12 (.pfx) 檔案,內含私鑰。
  • 可以一次簽署所有頁面嗎? 可以——在選項中設定 allPages(true)。
  • 如何加入時間戳記? 使用 options.setTimestampOptions(...) 並提供受信任的 TSA URL。
  • 支援哪個 Java 版本? JDK 8 或以上;建議在生產環境使用 JDK 11。

什麼是 “how to sign pdf”?

how to sign pdf 指的是將具加密安全性的數位簽章套用於 PDF 文件,以便驗證其完整性與作者身分。GroupDocs.Signature 實作 PDF ISO 32000‑1 標準,確保簽章能被 Adobe Acrobat 及其他閱讀器辨識。

為什麼要使用 GroupDocs.Signature for Java?

GroupDocs.Signature 支援 50+ 輸入與輸出格式,能在不將整個檔案載入記憶體的情況下處理 500+ 頁 的 PDF,並內建時間戳記功能。其 API 讓您只需幾行程式碼即可建立專業外觀的簽章區塊,較低階 PDF 函式庫大幅減少開發工作量。

前置條件

  • Java 基礎 – 了解類別、物件,以及 Maven/Gradle 的基本使用。
  • IDE – IntelliJ IDEA、Eclipse 或任何支援 Java 的編輯器。
  • 建置工具 – Maven 或 Gradle(兩者皆有說明)。
  • 數位憑證 – .pfx 檔案(測試用自簽,正式環境使用 CA 簽發)。
  • JDK – 8 版或更新;建議使用 JDK 11 以上以獲得最佳效能。

關於數位憑證

數位憑證就是您的電子身分證。正式環境請向受信任的憑證機構(如 DigiCert、GlobalSign)取得。開發時可使用 keytool 產生自簽憑證(請參閱下方「開發/測試」章節)。

設定 GroupDocs.Signature for Java

使用 Maven 安裝

在 pom.xml 中加入以下相依性:

<!-- ```xml
<dependency>
    <groupId>com.groupdocs</groupId>
    <artifactId>groupdocs-signature</artifactId>
    <version>23.12</version>
</dependency>
``` -->

為什麼是 23.12 版? 這是穩定版,包含所有 PDF 簽署功能,且已在企業環境中驗證。較新版本向前相容,但 23.12 可保證本教學所使用的 API 介面。

使用 Gradle 安裝

若您偏好 Gradle,請在 build.gradle 中加入:

// ```gradle
implementation 'com.groupdocs:groupdocs-signature:23.12'

編輯後同步專案以下載函式庫——跳過此步驟是常見的「找不到類別」錯誤根源。

取得授權

GroupDocs.Signature 為商業產品。依需求選擇以下方案:

  1. 免費試用 – 適合評估。立即取得
  2. 暫時授權 – 延長評估期。申請授權
  3. 正式授權 – 生產環境使用。立即購買

本教學使用免費試用即可完成。

如何在 Java 中以程式方式簽署 PDF:逐步實作

以下將實作分為聚焦的問答式章節。每個章節先給出 40‑70 字的直接回答,接著說明與相關程式碼佔位符。

如何初始化 Signature 物件?

建立一個 Signature 實例以包裹目標 PDF 檔案;此動作會將文件載入記憶體並為簽署做準備。

// ```java
Signature signature = new Signature("YOUR_DOCUMENT_DIRECTORY/samplePdf.pdf");

定義說明:Signature 類別是 GroupDocs.Signature 用來載入、修改與儲存 PDF 的入口點。

如何設定數位簽章選項?

設定憑證路徑、密碼、原因與位置。這些資訊會成為加密簽章的一部份,並在 PDF 閱讀器中顯示。

// ```java
DigitalSignOptions options = new DigitalSignOptions("YOUR_DOCUMENT_DIRECTORY/certificate.pfx");
options.setPassword("1234567890"); // 您的憑證密碼
options.setReason("Approved"); // 簽署原因(會出現在 PDF 中)
options.setLocation("New York"); // 簽署地點

定義說明:DigitalSignOptions 包含數位簽章所需的所有參數,包含視覺外觀與加密設定。

如何自訂簽章外觀?

調整標籤、符號、背景色與字型,以符合企業品牌或合規指引。

// ```java
PdfDigitalSignatureAppearance appearance = new PdfDigitalSignatureAppearance();
appearance.setContactInfoLabel("");
appearance.setReasonLabel("R:");
appearance.setLocationLabel("@⇒");
appearance.setDigitalSignedLabel("By:");
appearance.setDateSignedAtLabel("On");
appearance.setBackground(java.awt.Color.red);
appearance.setFontFamilyName("Courier");
appearance.setFontSize(8);

options.setAppearance(appearance);

定義說明:SignatureAppearance 定義最終使用者在 PDF 中看到的簽章區塊視覺呈現。

如何定位與調整簽章區塊大小?

指定頁面選擇、尺寸、對齊方式與邊距,以精確控制簽章出現位置。

// ```java
options.setAllPages(true); // 套用至所有頁面
options.setWidth(160); // 寬度(像素)
options.setHeight(80); // 高度(像素)
options.setVerticalAlignment(VerticalAlignment.Center);
options.setHorizontalAlignment(HorizontalAlignment.Left);
options.setMargin(new Padding(0, 10, 0, 10)); // 上、右、下、左邊距

定義說明:SignatureOptions(或其子類)負責可見簽章的放置、尺寸與頁面範圍。

如何為簽章加上可見邊框?

邊框能讓簽章更突出,並告知審閱者簽署區域所在。

// ```java
Border border = new Border();
border.setVisible(true);
border.setColor(java.awt.Color.red);
border.setDashStyle(DashStyle.DashDot);
border.setWeight(2); // 粗細(像素)
options.setBorder(border);

定義說明:Border 設定簽章框線的樣式、粗細與可見性。

如何簽署文件並儲存結果?

呼叫 sign 並傳入已設定好的選項;方法會回傳 SignResult,其中包含成功與警告資訊。

// ```java
SignResult signResult = signature.sign("YOUR_OUTPUT_DIRECTORY/digitallySignedPdfAppearance.pdf", options);

定義說明:SignResult 提供簽署作業的詳細資訊,包括成功簽署的頁數。

如何驗證簽署是否成功?

檢查 SignResult 物件;若 isSuccessful() 為 true,表示 PDF 已包含有效的數位簽章。

// ```java
if (signResult.getSucceeded().size() > 0) {
    System.out.println("Document signed successfully!");
} else {
    System.err.println("Signing failed: " + signResult.getFailed());
}

常見問題與避免方式

問題 1:「找不到憑證」錯誤

直接回答: 開發期間請使用絕對路徑指向 .pfx 檔,正式環境則將憑證置於應用程式目錄之外,並透過環境變數引用。

// ```java
String certPath = System.getenv("CERTIFICATE_PATH");
DigitalSignOptions options = new DigitalSignOptions(certPath);

問題 2:密碼錯誤例外

直接回答: 確認密碼與建立憑證時使用的相同;密碼區分大小寫,且應從安全保管庫取得,避免硬編碼。

// ```java
// 良好做法
DigitalSignOptions options = new DigitalSignOptions("cert.pfx");
signature.sign("output.pdf", options);

// 之後簽署其他文件
DigitalSignOptions newOptions = new DigitalSignOptions("cert.pfx"); // 重新建立物件
signature.sign("output2.pdf", newOptions);

問題 3:簽章出現在錯誤頁面

直接回答: 每次簽署前建立全新的 DigitalSignOptions 物件;重複使用同一物件會保留舊的頁面設定。

// ```java
options.setWidth(320); // 改為 320
options.setHeight(160); // 改為 160

問題 4:簽章渲染模糊

直接回答: 增大簽章區塊的像素尺寸(例如寬 320、高 160),以取得 300 DPI 的列印品質。

// ```bash
java -Xmx2G -jar your-application.jar

問題 5:大型 PDF 發生 OutOfMemoryError

直接回答: 增加 JVM 堆積大小(-Xmx2g),並在使用完畢後關閉 Signature 物件;它實作 AutoCloseable 可釋放原生資源。

// ```java
try (Signature signature = new Signature("document.pdf")) {
    signature.sign("signed.pdf", options);
} // 自動釋放資源

生產環境安全最佳實踐

絕不要硬編碼憑證密碼

將密碼存放於祕密管理服務(AWS Secrets Manager、Azure Key Vault、HashiCorp Vault),於執行時載入。

// ```java
// BAD - 不要這樣做
options.setPassword("1234567890");

// GOOD - 從環境變數或保管庫載入
String password = System.getenv("CERT_PASSWORD");
options.setPassword(password);

限制憑證檔案權限

在 Linux 上將權限設為 400(僅擁有者可讀),防止未授權存取。

// ```bash
chmod 400 /secure/certificates/signing-cert.pfx

使用時間戳記確保長期有效性

加入受信任的時間戳記伺服器(TSA),即使簽章憑證過期,簽章仍保持有效。

// ```java
options.setTimestampUrl("http://timestamp.digicert.com");

簽署後立即驗證

執行驗證流程,確保簽章正確嵌入且 PDF 閱讀器能辨識。

// ```java
SignResult result = signature.sign("output.pdf", options);
if (result.getSucceeded().size() > 0) {
    // 驗證簽章
    VerifyResult verifyResult = signature.verify();
    if (!verifyResult.isValid()) {
        throw new SecurityException("Signature verification failed!");
    }
}

記錄每一次簽署操作

保留包含使用者 ID、文件 ID、時間戳記與憑證指紋等資訊的稽核日誌。

// ```java
logger.info("Document signed: {}, User: {}, Timestamp: {}", 
    documentName, currentUser, LocalDateTime.now());

為您的使用情境選擇合適的憑證

開發 / 測試 – 自簽

使用 Java 的 keytool 快速產生;適合內部示範,但 不適用 正式法律文件。

// ```bash
keytool -genkeypair -alias testcert -keyalg RSA -keysize 2048 \
  -keystore test.pfx -storetype PKCS12 -validity 365

正式環境 – 商業 CA

購買 文件簽署憑證(DigiCert、GlobalSign),年費約 $70‑$400。此類憑證受到所有主流 PDF 閱讀器信任。

企業內部 – 自建 CA

自行營運憑證機構,可無限制產生內部憑證。請注意:內部 CA 不會被組織外部信任。

真實案例與實作

合約管理系統

  • 目標: 為多頁 NDA 的每一頁簽署。
  • 實作: allPages(true)、右下角放置、使用時間戳記伺服器、記錄稽核。
  • 效能建議: 使用固定大小執行緒池以平行批次處理合約。

發票自動化

  • 目標: 在發票首頁加入隱蔽簽章。
  • 實作: allPages(false)、最小化外觀、無邊框、以公司標誌作為背景圖。

醫療紀錄系統(HIPAA)

  • 目標: 確保出院摘要由主診醫師簽署。
  • 實作: 簽章外觀加入醫師資格資訊、高保證 CA 憑證、雙因素保護私鑰。

政府文件處理

  • 目標: 為公共部門表單套用多層審批(多重簽章)。
  • 實作: 依序呼叫 sign,每次使用不同的 DigitalSignOptions,各自帶有獨立憑證與時間戳記。

效能優化技巧

在批次作業中重複使用 Signature 物件

// ```java
try (Signature signature = new Signature("template.pdf")) {
    for (Document doc : documents) {
        signature.sign(doc.getOutputPath(), getOptionsForDoc(doc));
    }
}

快取已載入的憑證

// ```java
// 只載入一次憑證
DigitalSignOptions baseOptions = new DigitalSignOptions("cert.pfx");
baseOptions.setPassword(certPassword);

// 為每份文件複製
for (Document doc : documents) {
    DigitalSignOptions options = baseOptions.clone();
    options.setReason(doc.getReason());
    signature.sign(doc.getPath(), options);
}

為高吞吐量調校 JVM

// ```bash
java -Xmx4G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar app.jar

非同步簽署文件

// ```java
CompletableFuture.supplyAsync(() -> {
    signature.sign(outputPath, options);
    return "Success";
}).thenAccept(result -> notifyUser(result));

疑難排解指南

問題快速檢查解決方法
簽章未顯示border.setVisible(true)? 寬度/高度 > 0?座標是否在頁面外?暫時設定亮色背景以定位簽章區塊。
「憑證無效」檢查憑證是否過期(keytool -list -v -keystore cert.pfx)。使用有效且未過期的憑證;如有需要,轉換為 PKCS#12 格式。
已簽署的 PDF 無法開啟磁碟空間?檔案權限?PDF 版本相容性?保持原始檔案不變,將簽署後的 PDF 寫入新路徑。

常見問答

Q: 可以在生產環境免費使用 GroupDocs.Signature 嗎?
A: 不行。免費試用僅供評估使用,正式部署必須購買授權。

Q: 數位簽章與電子簽章有何不同?
A: 數位簽章使用加密憑證保證真實性並偵測篡改;電子簽章僅是手寫簽名的數位化表示。

Q: 能否簽署受密碼保護的 PDF?
A: 能——在開啟文件時提供 PDF 密碼:

// ```java
LoadOptions loadOptions = new LoadOptions();
loadOptions.setPassword("pdfPassword");
Signature signature = new Signature("protected.pdf", loadOptions);

您可以從官方頁面下載最新函式庫版本:Grab it here。
若需暫時評估授權,請使用申請表單:Request one。
準備好投入生產時,請購買正式授權:Purchase here 或 purchase a license。

Q: 如何在同一 PDF 上套用多個簽章?
A: 依序呼叫 sign,傳入不同的 DigitalSignOptions,或將選項陣列傳入以逐一簽署。

Q: 簽章能在行動裝置的 PDF 閱讀器上正常顯示嗎?
A: 完全可以。GroupDocs.Signature 產生符合 ISO 標準的簽章,能在 Adobe Reader、iOS Preview 以及 Android PDF 閱讀器上正確渲染。

Q: 一般 PDF 簽署需要多長時間?
A: 10 頁文件大約 200‑500 ms;100 頁且含時間戳記的文件約 1‑3 秒。

Q: 若憑證在簽署後過期會怎樣?
A: 若使用了時間戳記伺服器,簽章仍然有效,因為 TSA 證明簽署時間發生於憑證仍受信任的期間。

後續步驟與深入學習

  • 簽章驗證 – 學習如何以程式方式驗證現有簽章。
  • 批次簽署 – 使用前述平行模式將簽署規模擴展至千級文件。
  • QR‑code 簽章 – 嵌入可掃描的 QR Code 以快速驗證。
  • 整合 – 將簽署服務串接至 SharePoint、Alfresco 或自訂 REST API。

有用資源


最後更新: 2026-06-26
測試環境: GroupDocs.Signature 23.12 for Java
作者: GroupDocs

相關教學