如何使用 Java 為 PDF 簽署並加上時間戳記
當您需要保護合約、發票或任何關鍵文件免於被竄改時,如何簽署 PDF 的安全性就成為首要任務。在本指南中,您將學會如何使用 GroupDocs.Signature for Java 為 PDF 添加數位簽章與受信任的時間戳記。此方法可離線執行,支援最高 500 MB 的檔案,且只需幾行程式碼。
快速回答
- 哪個函式庫簡化了 Java 中的 PDF 簽署? GroupDocs.Signature for Java。
- 我需要網際網路連線嗎? 僅在時間戳記授權機構需要;加密簽署在本機執行。
- 我可以使用自簽憑證進行測試嗎? 可以,使用
keytool產生。 - 有大小限制嗎? 此函式庫可簽署最高 500 MB 的 PDF,且不會將整個檔案載入記憶體。
- GroupDocs 支援多少種格式? 超過 50 種輸入與輸出格式,包括 DOCX、XLSX、PPTX、HTML 與影像。
如何使用 Java 簽署 PDF?
載入 PDF,使用您的憑證配置 DigitalSignature,可選擇從符合 RFC 3161 的 TSA 附加時間戳記,然後呼叫 sign()。Signature 物件會將已簽署的檔案寫入磁碟,回傳一個 SignResult,告訴您操作是否成功並列出任何警告。這個端對端流程只需幾行 Java 程式碼,且會自動處理雜湊、憑證驗證與時間戳記取得。
為何數位簽章重要(以及為何需要時間戳記)
數位簽章保證 authenticity(簽署者身分)與 integrity(文件未被更改)。加入時間戳記可證明簽章在特定時刻已存在,即使簽署憑證之後過期或被撤銷,仍能提供保護。兩者結合提供不可否認性——對法律、金融與合規工作流程至關重要。
設定 GroupDocs.Signature for Java
整合方式
挑選您偏好的建置工具:
對於 Maven 使用者
將相依性加入您的 pom.xml:
以下 Maven 坐標會取得最新穩定版的 GroupDocs.Signature for Java。
<dependency>
<groupId>com.groupdocs</groupId>
<artifactId>groupdocs-signature</artifactId>
<version>23.12</version>
</dependency>
對於 Gradle 使用者
將此行加入您的 build.gradle:
Gradle 會從 Maven Central 解析此函式庫。
implementation 'com.groupdocs:groupdocs-signature:23.12'
直接下載(如果您偏好)
前往 GroupDocs.Signature for Java releases 下載 JAR 檔。手動將其加入專案的 classpath。參閱 GroupDocs.Signature Documentation 取得完整 API 參考。欲取得最新建置,請見 Latest Version & Releases。
Pro tip: Maven 或 Gradle 會自動化版本升級與傳遞相依性,讓您在發布新安全修補程式時節省時間。
取得授權
GroupDocs 提供三種授權選項:
- Free trial – 評估所有功能且不會加上浮水印。 Download Trial Version
- Temporary license – 30 天完整存取金鑰,供開發使用。
- Commercial license – 生產環境就緒,無限制使用。 Buy License
如果有任何問題,社群活躍於 GroupDocs Forum。
基本初始化
Signature 是 GroupDocs.Signature 的頂層物件,代表記憶體中的單一 PDF 檔案。建立實例後,所有讀寫操作皆透過它執行。
import com.groupdocs.signature.Signature;
String filePath = "YOUR_DOCUMENT_DIRECTORY/sample.pdf";
final Signature signature = new Signature(filePath);
如何在 Java 中為 PDF 添加數位簽章:逐步說明
此流程為線性步驟:匯入類別、設定檔案路徑、建立 Signature 物件、配置帶可選時間戳記的 DigitalSignature、定義 SignOptions,最後簽署並儲存。
步驟 1:匯入必要的類別
以下匯入讓您能使用簽章配置、定位與時間戳記功能。
import com.groupdocs.signature.Signature;
import com.groupdocs.signature.domain.enums.HorizontalAlignment;
import com.groupdocs.signature.domain.enums.VerticalAlignment;
import com.groupdocs.signature.domain.signatures.PdfDigitalSignature;
import com.groupdocs.signature.domain.structs.TimeStamp;
import com.groupdocs.signature.options.sign.DigitalSignOptions;
步驟 2:定義檔案路徑
設定輸入 PDF、憑證(PFX)以及輸出位置的路徑。務必保護憑證檔案的安全,因為它包含您的私鑰。
String filePath = "YOUR_DOCUMENT_DIRECTORY/sample.pdf";
String certificatePath = "YOUR_DOCUMENT_DIRECTORY/certificate.pfx";
String outputFilePath = "YOUR_OUTPUT_DIRECTORY/digitallySignedTimeStamp.pdf";
步驟 3:初始化 Signature 物件
Signature 是所有簽署動作的入口點。建立它會將 PDF 載入記憶體,並為後續操作做好 API 準備。
final Signature signature = new Signature(filePath);
步驟 4:設定簽章屬性與時間戳記
DigitalSignature 是將嵌入 PDF 的加密封印。您也可以從受信任的授權機構附加時間戳記。
PdfDigitalSignature pdfDigitalSignature = new PdfDigitalSignature();
pdfDigitalSignature.setContactInfo("Contact Information");
pdfDigitalSignature.setLocation("Location Info");
pdfDigitalSignature.setReason("Signing Reason");
// Configure the TimeStamp with URL, User Id, and Password
TimeStamp timeStamp = new TimeStamp("https://freetsa.org/tsr", "User Id", "Password");
pdfDigitalSignature.setTimeStamp(timeStamp);
- ContactInfo – 例如,
john.doe@company.com - Location – 例如,
New York Office - Reason – 例如,
Contract Approval
我們在示範中使用 FreeTSA(免費時間戳記授權機構)。在正式環境中,請選擇商業 TSA 以確保正常運作與法律效力。
步驟 5:設定數位簽章選項
SignOptions 彙總了憑證、視覺外觀與數位簽章的放置設定。
DigitalSignOptions options = new DigitalSignOptions(certificatePath);
options.setPassword("YourCertificatePassword"); // Certificate password
options.setSignature(pdfDigitalSignature); // Attach the PdfDigitalSignature object
// Specify signature alignment (where it appears on the page)
options.setVerticalAlignment(VerticalAlignment.Bottom);
options.setHorizontalAlignment(HorizontalAlignment.Right);
步驟 6:簽署並儲存文件
SignResult 提供簽署操作的結果,包括成功狀態與任何警告。
try {
SignResult signResult = signature.sign(outputFilePath, options);
System.out.println("Document signed successfully!");
System.out.println("Output: " + outputFilePath);
} catch (Exception e) {
throw new RuntimeException("Error during signing process: " + e.getMessage());
}
常見陷阱須避免
1. 憑證問題
Problem: “Invalid certificate” errors.
Fix: Verify the password with keytool -list -v -keystore your.pfx.
keytool -list -v -keystore certificate.pfx -storetype PKCS12
2. 時間戳記服務逾時
Problem: Network timeouts when contacting the TSA.
Fix: Test connectivity (curl -I https://freetsa.org/tsr), add retry logic, or configure a fallback TSA.
new File(outputFilePath).getParentFile().mkdirs();
3. 檔案權限問題
Problem: “Access denied” while saving.
Fix: Ensure the output directory exists and the application has write permissions.
keytool -genkeypair -alias mykey -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore certificate.pfx -validity 365
4. 大型 PDF 記憶體問題
Problem: OutOfMemoryError for big files.
Fix: Increase JVM heap (-Xmx4g) or process files in batches.
5. 簽章位置錯誤
Problem: Signature overlaps existing content.
Fix: Test alignment settings first; for pixel‑perfect placement, use coordinate‑based options.
憑證管理技巧
取得開發用憑證
產生自簽憑證以供測試,使用 Java 的 keytool。
String certPassword = System.getenv("CERT_PASSWORD");
憑證最佳實踐
- Never hard‑code passwords – use environment variables.
- Rotate certificates before they expire.
- Store private keys in secure hardware (HSM) for high‑security apps.
- Back up certificates in a protected location.
- Validate certificates before signing to catch expired or revoked ones.
安全最佳實踐
1. 保護私鑰
將憑證儲存在專案目錄之外,使用環境特定的設定,企業部署時考慮使用 HSM。
2. 驗證輸入 PDF
在簽署前檢查檔案是否損毀、是否已有簽章、大小限制以及內容合規性。
3. 實作稽核日誌
記錄每一次簽署操作的時間戳記、使用者、文件名稱與狀態。
try {
SignResult result = signature.sign(outputFilePath, options);
logger.info("Document signed: " + filePath + " by " + signerEmail);
} catch (Exception e) {
logger.error("Signing failed: " + filePath + " - " + e.getMessage());
// Handle appropriately
}
4. 使用受信任的時間戳記授權機構
絕不要依賴本機系統時間;始終向符合 RFC 3161 的 TSA 請求時間戳記。
5. 實作錯誤處理
捕捉例外而不洩漏敏感細節。
try {
signature.sign(outputFilePath, options);
} catch (Exception e) {
// Log detailed error internally
logger.error("Signing error: " + e.getMessage(), e);
// Return generic error to client
throw new ApplicationException("Unable to sign document. Please try again.");
}
實務案例與應用
- Contract management systems – employees sign NDAs and agreements electronically; timestamps prove exactly when each contract was accepted.
- Financial document processing – batch‑sign invoices and purchase orders, providing an immutable audit trail for regulators.
- Educational credential verification – universities issue tamper‑proof transcripts that can be instantly validated via a QR‑code link.
- Software license management – generate license certificates with a digital signature and timestamp to prevent forgery.
- Regulatory compliance (FDA 21 CFR Part 11, etc.) – medical device firms sign SOPs and validation reports; timestamps satisfy non‑repudiation requirements.
效能考量與最佳化
記憶體管理
將大型 PDF 分批處理,及時關閉 Signature 物件,必要時增大堆疊大小。
時間戳記的網路最佳化
使用連線池、實作指數退避重試,並快取時間戳記以加速連續簽署。
批次處理最佳實踐
// Pseudo‑code: process a list of PDFs in parallel, limiting to 5 concurrent TSA calls
避免產生過多執行緒;5‑10 個同時簽署的執行緒可在效能與 TSA 負載之間取得平衡。
磁碟 I/O 最佳化
使用 SSD 作為暫存檔案,減少讀寫循環,並在每次簽署後清理暫存產物。
故障排除指南
錯誤:「Invalid certificate password」
Solution: Verify the password with keytool -list -keystore your.pfx.
ExecutorService executor = Executors.newFixedThreadPool(5);
List<Future<SignResult>> futures = new ArrayList<>();
for (String pdfPath : pdfPaths) {
futures.add(executor.submit(() -> {
try (Signature sig = new Signature(pdfPath)) {
return sig.sign(outputPath, options);
}
}));
}
// Wait for all to complete
for (Future<SignResult> future : futures) {
SignResult result = future.get();
// Process result
}
executor.shutdown();
錯誤:「Timestamp authority not responding」
Solution: Test the TSA URL, check firewall rules, and add fallback TSA logic.
keytool -list -v -keystore certificate.pfx -storetype PKCS12
錯誤:「PDF is already signed」
Solution: Detect existing signatures first; either add a counter‑signature or sign a fresh copy.
錯誤:「Access denied」於儲存時
Solution: Ensure the output directory exists, the app has write rights, and no other process locks the file.
TimeStamp timeStamp;
try {
timeStamp = new TimeStamp("https://freetsa.org/tsr", "", "");
} catch (Exception e) {
// Fallback to alternative TSA
timeStamp = new TimeStamp("https://alternate-tsa.com/tsr", "", "");
}
錯誤:OutOfMemoryError
Solution: Increase JVM heap, process PDFs in smaller batches, or switch to streaming APIs for very large files.
結論與後續步驟
您現在已了解 如何簽署 PDF 檔案的 Java 實作方式、如何加入受信任的時間戳記,以及如何避免常見陷阱。接下來您可以:
- 為多方協議新增多個簽章欄位。
- 使用 GroupDocs.Signature 以程式方式驗證簽章。
- 自訂簽章的視覺外觀(圖像、文字、定位)。
- 建置具佇列與監控功能的穩健批次簽署服務。
常見問題
Q: 數位簽章與電子簽章有何差異?
A: 數位簽章使用加密演算法驗證身分與偵測竄改,而電子簽章可能僅是打字的姓名。
Q: 簽署 PDF 時需要網路連線嗎?
A: 僅在使用時間戳記服務時需要;加密簽署本身在本機執行。
Q: 已簽署的 PDF 之後可以編輯嗎?
A: 任何修改都會破壞簽章,PDF 閱讀器會顯示文件已被更改的警告。
Q: 如何驗證已簽署的 PDF?
A: 大多數 PDF 閱讀器會自動驗證;程式上可使用 GroupDocs.Signature 的驗證 API 檢查狀態、簽署者資訊與時間戳記有效性。
Q: 若我的憑證在簽署後過期,會怎樣?
A: 嵌入的時間戳記證明簽章在憑證仍有效時已完成,從而保留法律效力。
Q: 可以將此流程與雲端儲存(S3、Azure Blob 等)結合嗎?
A: 可以——先將 PDF 下載至暫存位置簽署,然後再上傳已簽署的版本回雲端。
Q: 有檔案大小限制嗎?
A: 此函式庫可處理最高 500 MB 的 PDF,且不會一次載入全部檔案;較大的檔案可能需要使用串流方式。
Q: GroupDocs.Signature 的商業授權費用多少?
A: 價格依部署類型而異,請聯絡 GroupDocs 銷售取得最新報價。亦提供免費試用與臨時授權供評估使用。
Q: 這在 Linux 伺服器上可運作嗎?
A: 完全可以。GroupDocs.Signature for Java 為平台無關,能在任何安裝 JRE 的作業系統上執行。
Last Updated: 2026-09-05
Tested With: GroupDocs.Signature 23.9 for Java
Author: GroupDocs
相關教學
- 如何在 Java 中驗證數位憑證 - 完整指南與程式碼範例
- 如何使用 GroupDocs.Signature 在 Java 中程式化簽署 PDF
- 在 Java 中使用 GroupDocs 為 PDF 加入圖像簽章
File outputFile = new File(outputFilePath);
outputFile.getParentFile().mkdirs(); // Create directories if needed
if (!outputFile.canWrite() && outputFile.exists()) {
throw new IOException("Cannot write to " + outputFilePath);
}