如何在Java中对PDF进行数字签名

This article was translated from English: Does it need improvement?
Translated
View the article in English

在Java中使用IronPDF对PDF进行数字签名,让您可以应用加密签名,以验证文档的真实性并检测未授权的更改。 IronPDF 支持 PdfSignature,用于将基于 PFX 证书的签名附加到任何 PDF 文件、设置可见的签名图像、通过 PdfCertificationLevel 控制 PDF 认证级别,以及连接到时间戳权威机构服务器以确保签名的长期有效性。

快速开始:在Java中对PDF进行数字签名

  1. 通过Maven或Gradle安装IronPDF for Java
  2. 使用 License.setLicenseKey() 设置您的许可证密钥
  3. 加载 PDF 文件 PdfDocument.fromFile()
  4. 使用您的 PFX 证书文件和密码创建一个 PdfSignature
  5. 添加签名 signDigitalSignature()
  6. 保存带签名的 PDF 文件 saveAs()

```java :title=快速入门 //:path=/static-assets/ironpdf-java/content-code-examples/how-to/how-to-digitally-sign-pdfs-java-tutorial/quickstart.java 导入 java.io.IOException; import java.nio.file.Path; import com.ironsoftware.IronPdf.License; import com.ironsoftware.IronPdf.PdfDocument; import com.ironsoftware.ironpdf.signature.PdfSignature;

public class Main { public static void main(String[] args) throws IOException { // 设置IronPDF许可证密钥 License.setLicenseKey("IronPDF-MYLICENSE-KEY-1EF01");

    // 加载现有的PDF文档
    PdfDocument pdf = PdfDocument.fromFile(Path.of("document.pdf"));

    // 使用PFX证书文件及其密码创建PdfSignature
    PdfSignature signature = new PdfSignature("certificate.pfx", "password123");

    // 设置签名元数据以进行审计追踪
    signature.setSigningContact("John Smith");
    signature.setSigningLocation("New York");
    signature.setSigningReason("文档审批");

    // 将数字签名应用于PDF
    pdf.signDigitalSignature(signature);

    // 将签名的PDF保存为新文件
    pdf.saveAs(Path.of("signed.pdf"));
}

}


数字签名为PDF文档提供了一种与私钥和证书相关联的加密身份。 当收件人在Adobe Acrobat或任何兼容的查看器中打开签署的PDF时,应用程序会验证证书链是否追溯到受信的权威机构,并确认文档内容自签署以来未发生变化。 这种结合身份验证和完整性的方式使得数字签名对于合同、发票、法规备案以及任何涉及防篡改的文档来说都是必不可少的。

PDF签名分为两类:批准签名和作者(认证)签名。 批准签名记录一个签名者在特定时间点的批准;多个方可以顺序添加批准签名而不会使之前的签名失效。 使用 `certify()` 应用的认证签名会根据 `PdfCertificationLevel` 锁定文档,并将签名者标记为文档作者。 认证签名必须是文档上的第一个签名,并控制后续签名者可以进行的任何更改(如果有的话)。

IronPDF 通过基于 `PdfSignature` 和 `PdfDocument` 构建的统一 API 支持这两种签名类型。 有关初始设置、依赖项配置和许可证密钥说明,请参阅[入门概览](https://ironpdf.com/java/docs/)。

<div class="hsg-featured-snippet">
    <h2>如何在Java中对PDF进行数字签名</h2>
    <ol>
        <li><a href="https://ironpdf.com/java/#download-modal">安装IronPDF Java库进行数字签名</a></li>
        <li>使用<strong>PdfDocument</strong>类加载PDF</li>
        <li>使用PFX证书文件和密码创建<strong>PdfSignature</strong></li>
        <li>可选地使用<code>setSignatureImage</code>设置可见签名图像</li>
        <li>用<code>signDigitalSignature</code>应用签名</li>
        <li>使用<code>certify</code>和<code>PdfCertificationLevel</code>认证PDF</li>
        <li>用<code>saveAs</code>保存签名的PDF</li>
    </ol>
</div>

## 开始之前我需要什么?

在使用IronPDF签署PDF之前,请确认以下前提条件:

- **Java 8或更高版本**:IronPDF需要JDK 8或更高版本。
- **IronPDF for Java**:将依赖项添加到您的构建文件中。在[Maven Central](https://central.sonatype.com/artifact/com.ironsoftware/ironpdf)上找到最新版本。
- **有效的许可证密钥**:在应用程序启动时使用 `License.setLicenseKey()` 设置密钥。 有关设置详情,请访问[许可证密钥指南](https://ironpdf.com/java/get-started/license-keys/)。
- **PFX或P12证书文件**:这是一个包含您私钥和公钥证书的受密码保护的存档,采用PKCS#12格式。 自签名证书适用于开发和测试; 对于需要被外部接收者信任的生产文档,请使用由DigiCert、Comodo或GlobalSign等公认的证书颁发机构(CA)颁发的证书。

有关完整的依赖项设置和项目配置,请参阅[入门概览](https://ironpdf.com/java/docs/)。

## 如何为PDF应用数字签名?

`PdfSignature` 构造函数接受您的 PFX 证书的文件路径及其密码。 构造完成后,您可以通过三个setter方法附加可选的元数据:

- `setSigningContact(String)`:签署人的姓名或电子邮件地址
- `setSigningLocation(String)`:签署人的物理或组织位置
- `setSigningReason(String)`:关于为何对该文档进行签名的简要说明

这些字段显示在PDF查看器的签名属性面板中,为合规目的创建了有用的审计记录。 在加载的 `PdfDocument` 上调用 `signDigitalSignature(PdfSignature)` 以嵌入加密签名,然后使用 `saveAs()` 保存结果。

```java
//:path=/static-assets/ironpdf-java/content-code-examples/how-to/how-to-digitally-sign-pdfs-java-tutorial/apply-signature.java
导入 java.io.IOException;
import java.nio.file.Path;
import com.ironsoftware.IronPdf.License;
import com.ironsoftware.IronPdf.PdfDocument;
import com.ironsoftware.ironpdf.signature.PdfSignature;

public class Main {
public static void main(String[] args) throws IOException {
        // 设置IronPDF许可证密钥
        License.setLicenseKey("IronPDF-MYLICENSE-KEY-1EF01");

        // Load the PDF to sign
        PdfDocument pdf = PdfDocument.fromFile(Path.of("contract.pdf"));

        // Construct the PdfSignature with the certificate path and password
        PdfSignature signature = new PdfSignature("certificate.pfx", "password123");

        // Set metadata that will appear in the signature properties panel
        signature.setSigningContact("Jane Doe");
        signature.setSigningLocation("Austin, TX");
        signature.setSigningReason("Contract Approval");

        // Embed the digital signature in the PDF
        pdf.signDigitalSignature(signature);

        // Save the signed document
        pdf.saveAs(Path.of("contract-signed.pdf"));
    }
}

完成 signDigitalSignature() 操作后,PDF 文件中将包含文档内容的加密哈希值,该哈希值使用 PFX 文件中的私钥进行签名。此后对文件的任何修改都将导致签名失效。

如何在PDF中添加可见签名图像?

可见签名图像将图形表示直接放置在PDF页面上的签名字段位置。 这通常用于显示扫描的手写签名、公司印章或徽标,以便在打印或查看时文件看起来像已签署,而不仅仅是在用PDF阅读器的签名面板检查时。

要添加可见图片,请将图片文件作为 FileInputStream 打开,并在调用 signDigitalSignature() 之前将其传递给 PdfSignature.setSignatureImage(InputStream)。 图像嵌入在页面上的签名字段内。

//:path=/static-assets/ironpdf-java/content-code-examples/how-to/how-to-digitally-sign-pdfs-java-tutorial/visible-signature-image.java
import java.io.FileInputStream;
导入 java.io.IOException;
import java.nio.file.Path;
import com.ironsoftware.IronPdf.License;
import com.ironsoftware.IronPdf.PdfDocument;
import com.ironsoftware.ironpdf.signature.PdfSignature;

public class Main {
public static void main(String[] args) throws IOException {
        // 设置IronPDF许可证密钥
        License.setLicenseKey("IronPDF-MYLICENSE-KEY-1EF01");

        // Load the PDF document to sign
        PdfDocument pdf = PdfDocument.fromFile(Path.of("agreement.pdf"));

        // Build the PdfSignature from a PFX certificate
        PdfSignature signature = new PdfSignature("certificate.pfx", "password123");

        // Set signing metadata
        signature.setSigningContact("Alice Johnson");
        signature.setSigningLocation("Chicago, IL");
        signature.setSigningReason("Agreement Authorization");

        // Open the signature image file and attach it to the signature
        FileInputStream imageStream = new FileInputStream("signature.png");
        signature.setSignatureImage(imageStream);

        // Apply the digital signature with the visible image to the PDF
        pdf.signDigitalSignature(signature);

        // Save the signed PDF with the visible signature image embedded
        pdf.saveAs(Path.of("agreement-signed.pdf"));
    }
}
//:path=/static-assets/ironpdf-java/content-code-examples/how-to/how-to-digitally-sign-pdfs-java-tutorial/visible-signature-image.java
import java.io.FileInputStream;
导入 java.io.IOException;
import java.nio.file.Path;
import com.ironsoftware.IronPdf.License;
import com.ironsoftware.IronPdf.PdfDocument;
import com.ironsoftware.ironpdf.signature.PdfSignature;

public class Main {
public static void main(String[] args) throws IOException {
        // 设置IronPDF许可证密钥
        License.setLicenseKey("IronPDF-MYLICENSE-KEY-1EF01");

        // Load the PDF document to sign
        PdfDocument pdf = PdfDocument.fromFile(Path.of("agreement.pdf"));

        // Build the PdfSignature from a PFX certificate
        PdfSignature signature = new PdfSignature("certificate.pfx", "password123");

        // Set signing metadata
        signature.setSigningContact("Alice Johnson");
        signature.setSigningLocation("Chicago, IL");
        signature.setSigningReason("Agreement Authorization");

        // Open the signature image file and attach it to the signature
        FileInputStream imageStream = new FileInputStream("signature.png");
        signature.setSignatureImage(imageStream);

        // Apply the digital signature with the visible image to the PDF
        pdf.signDigitalSignature(signature);

        // Save the signed PDF with the visible signature image embedded
        pdf.saveAs(Path.of("agreement-signed.pdf"));
    }
}
JAVA

签名图像不会取代加密保护; 图形印章和底层证书都仍然是签名输出的一部分。 PNG和JPEG格式支持签名图像。

如何用特定权限级别认证PDF?

认证PDF与添加批准签名不同。 当您调用 pdf.certify(PdfSignature, PdfCertificationLevel) 时,即以作者身份对文档进行签名,并指定后续用户被允许进行的修改类型。 认证的PDF会在Adobe Acrobat中显示蓝色丝带或类似的信任指示器,向接收者表明该文件来自经过验证的来源。

IronPDF 通过 PdfCertificationLevel 枚举提供三个认证级别:

  • PdfCertificationLevel.NO_CHANGES_ALLOWED:文档在认证后将被完全锁定; 不允许进一步修改。
  • PdfCertificationLevel.FORM_FILLING:收件人可以填写表单字段,但不能添加评论、注释或其他修改。
  • PdfCertificationLevel.FORM_FILLING_AND_ANNOTATIONS:收件人可以填写表单字段并添加注释,但仍禁止进行结构性编辑。

由于认证签名必须是文档上的第一个签名,因此在添加其他方的审批签名之前,请先调用 certify()

//:path=/static-assets/ironpdf-java/content-code-examples/how-to/how-to-digitally-sign-pdfs-java-tutorial/certify-pdf.java
导入 java.io.IOException;
import java.nio.file.Path;
import com.ironsoftware.IronPdf.License;
import com.ironsoftware.IronPdf.PdfDocument;
import com.ironsoftware.ironpdf.signature.PdfCertificationLevel;
import com.ironsoftware.ironpdf.signature.PdfSignature;

public class Main {
public static void main(String[] args) throws IOException {
        // 设置IronPDF许可证密钥
        License.setLicenseKey("IronPDF-MYLICENSE-KEY-1EF01");

        // Load the PDF that will be certified
        PdfDocument pdf = PdfDocument.fromFile(Path.of("report.pdf"));

        // Create the PdfSignature from the author's certificate
        PdfSignature signature = new PdfSignature("author-certificate.pfx", "password123");

        // Set author metadata for the certification signature
        signature.setSigningContact("Legal Department");
        signature.setSigningLocation("San Francisco, CA");
        signature.setSigningReason("Official Publication");

        // Certify the document with NO_CHANGES_ALLOWED to lock it completely
        // Use FORM_FILLING to allow form field input after certification
        // Use FORM_FILLING_AND_ANNOTATIONS to also permit annotations
        pdf.certify(signature, PdfCertificationLevel.NO_CHANGES_ALLOWED);

        // Save the certified PDF
        pdf.saveAs(Path.of("report-certified.pdf"));
    }
}
//:path=/static-assets/ironpdf-java/content-code-examples/how-to/how-to-digitally-sign-pdfs-java-tutorial/certify-pdf.java
导入 java.io.IOException;
import java.nio.file.Path;
import com.ironsoftware.IronPdf.License;
import com.ironsoftware.IronPdf.PdfDocument;
import com.ironsoftware.ironpdf.signature.PdfCertificationLevel;
import com.ironsoftware.ironpdf.signature.PdfSignature;

public class Main {
public static void main(String[] args) throws IOException {
        // 设置IronPDF许可证密钥
        License.setLicenseKey("IronPDF-MYLICENSE-KEY-1EF01");

        // Load the PDF that will be certified
        PdfDocument pdf = PdfDocument.fromFile(Path.of("report.pdf"));

        // Create the PdfSignature from the author's certificate
        PdfSignature signature = new PdfSignature("author-certificate.pfx", "password123");

        // Set author metadata for the certification signature
        signature.setSigningContact("Legal Department");
        signature.setSigningLocation("San Francisco, CA");
        signature.setSigningReason("Official Publication");

        // Certify the document with NO_CHANGES_ALLOWED to lock it completely
        // Use FORM_FILLING to allow form field input after certification
        // Use FORM_FILLING_AND_ANNOTATIONS to also permit annotations
        pdf.certify(signature, PdfCertificationLevel.NO_CHANGES_ALLOWED);

        // Save the certified PDF
        pdf.saveAs(Path.of("report-certified.pdf"));
    }
}
JAVA

一旦通过 NO_CHANGES_ALLOWED 认证,任何修改 PDF 的尝试都会破坏认证签名,PDF 阅读器将显示警告。 当需要下游接收方填写或标注经认证的文档,且不影响作者认证有效性时,请选择 FORM_FILLINGFORM_FILLING_AND_ANNOTATIONS

如何在数字签名中添加时间戳?

时间戳认证机构 (TSA) 服务器提供加密签名的时间令牌,该令牌嵌入在PDF签名旁。 该时间戳证明了签名的应用时间,与签名者的本地时钟无关。 长期有效性取决于时间戳:即使签名证书过期,可信的时间戳仍允许验证者确认签名是在证书仍然有效时创建的。

要启用时间戳功能,请在签名前为 PdfSignature 对象设置两个属性:

  • setTimestampHashAlgorithm(PdfHashAlgorithm):指定计算时间戳令牌时使用的哈希算法。 PdfHashAlgorithm.SHA256 是标准选择。
  • setTimestampUrl(String):TSA 服务器的 HTTP 或 HTTPS 端点,该端点将签发时间戳令牌。

几个TSA服务器可免费用于测试和低量生产使用。 https://freetsa.org/tsrhttp://timestamp.digicert.com 是两个常用的端点。

//:path=/static-assets/ironpdf-java/content-code-examples/how-to/how-to-digitally-sign-pdfs-java-tutorial/timestamp-signature.java
导入 java.io.IOException;
import java.nio.file.Path;
import com.ironsoftware.IronPdf.License;
import com.ironsoftware.IronPdf.PdfDocument;
import com.ironsoftware.ironpdf.signature.PdfHashAlgorithm;
import com.ironsoftware.ironpdf.signature.PdfSignature;

public class Main {
public static void main(String[] args) throws IOException {
        // 设置IronPDF许可证密钥
        License.setLicenseKey("IronPDF-MYLICENSE-KEY-1EF01");

        // Load the PDF to sign with a timestamp
        PdfDocument pdf = PdfDocument.fromFile(Path.of("invoice.pdf"));

        // Construct the PdfSignature from the certificate file
        PdfSignature signature = new PdfSignature("certificate.pfx", "password123");

        // Set signature metadata
        signature.setSigningContact("Finance Team");
        signature.setSigningLocation("Seattle, WA");
        signature.setSigningReason("Invoice Authorization");

        // Configure the timestamp: set the hash algorithm and TSA endpoint
        signature.setTimestampHashAlgorithm(PdfHashAlgorithm.SHA256);
        signature.setTimestampUrl("https://freetsa.org/tsr");

        // Apply the digital signature; IronPDF will contact the TSA to obtain
        // and embed a timestamp token alongside the cryptographic signature
        pdf.signDigitalSignature(signature);

        // Save the timestamped, signed PDF
        pdf.saveAs(Path.of("invoice-signed-timestamped.pdf"));
    }
}
//:path=/static-assets/ironpdf-java/content-code-examples/how-to/how-to-digitally-sign-pdfs-java-tutorial/timestamp-signature.java
导入 java.io.IOException;
import java.nio.file.Path;
import com.ironsoftware.IronPdf.License;
import com.ironsoftware.IronPdf.PdfDocument;
import com.ironsoftware.ironpdf.signature.PdfHashAlgorithm;
import com.ironsoftware.ironpdf.signature.PdfSignature;

public class Main {
public static void main(String[] args) throws IOException {
        // 设置IronPDF许可证密钥
        License.setLicenseKey("IronPDF-MYLICENSE-KEY-1EF01");

        // Load the PDF to sign with a timestamp
        PdfDocument pdf = PdfDocument.fromFile(Path.of("invoice.pdf"));

        // Construct the PdfSignature from the certificate file
        PdfSignature signature = new PdfSignature("certificate.pfx", "password123");

        // Set signature metadata
        signature.setSigningContact("Finance Team");
        signature.setSigningLocation("Seattle, WA");
        signature.setSigningReason("Invoice Authorization");

        // Configure the timestamp: set the hash algorithm and TSA endpoint
        signature.setTimestampHashAlgorithm(PdfHashAlgorithm.SHA256);
        signature.setTimestampUrl("https://freetsa.org/tsr");

        // Apply the digital signature; IronPDF will contact the TSA to obtain
        // and embed a timestamp token alongside the cryptographic signature
        pdf.signDigitalSignature(signature);

        // Save the timestamped, signed PDF
        pdf.saveAs(Path.of("invoice-signed-timestamped.pdf"));
    }
}
JAVA

当TSA在签名时无法访问时,IronPDF将抛出异常; 在部署到生产环境之前,验证网络访问和TSA端点URL。 对于高量生产工作流程,考虑购买商业TSA订阅以确保正常运行时间和吞吐量保证。

在Java中数字签名PDF的下一步是什么?

IronPDF 的 PdfSignature 类全面满足各类 PDF 签名需求:包含证书元数据的审批签名、可见的图形印章、带访问控制级别的 PDF 认证,以及由 TSA 支持的、确保长期有效性的时间戳。 要扩展您的PDF工作流以超出签名范围,请探索这些相关资源:

开始您的免费试用,将数字签名添加到您的Java PDF工作流程。 要购买用于生产使用的许可证,请查看许可证选项

常见问题解答

如何在Java中使用IronPDF数字签名PDF?

使用PdfDocument.fromFile()加载您的PDF,使用PFX证书文件路径及其密码创建PdfSignature,可选地通过setSigningContact()setSigningLocation()setSigningReason()设置元数据,然后调用pdf.signDigitalSignature(signature)并使用pdf.saveAs()保存。

IronPDF中的signDigitalSignature()和certify()有什么区别?

signDigitalSignature()添加记录一个签名者批准的批准签名。 可以按顺序添加多个批准签名。 certify()添加一个必须首先在文档中的作者签名,并设置一个PdfCertificationLevel,控制后续签名者可以进行的更改。

如何在Java中向已签名的PDF添加可见签名图像?

打开图像文件作为FileInputStream并在调用signDigitalSignature()之前将其传递给signature.setSignatureImage(imageStream)。 该图像嵌入在页面上的签名字段中,旁边是加密签名。

IronPDF支持哪些PDF认证级别?

IronPDF通过PdfCertificationLevel枚举支持三个级别:NO_CHANGES_ALLOWED完全锁定文档,FORM_FILLING仅允许表单字段输入,而FORM_FILLING_AND_ANNOTATIONS允许表单字段和注释但防止结构编辑。

如何在Java中向数字签名添加时间戳?

在调用signDigitalSignature()之前,设置signature.setTimestampHashAlgorithm(PdfHashAlgorithm.SHA256)signature.setTimestampUrl("https://freetsa.org/tsr")。 IronPDF与TSA服务器联系并在签名的PDF中嵌入时间戳记。

IronPDF需要哪种证书文件格式进行PDF签名?

IronPDF需要PFX或P12证书文件,这是一种包含私钥和公用证书的PKCS#12归档。 自签名证书适用于开发; 对于生产使用,请从受信任的证书颁发机构(如DigiCert或GlobalSign)获取证书。

在Java中使用IronPDF数字签名PDF的前提条件是什么?

您需要Java 8或更高版本,通过Maven或Gradle添加IronPDF依赖,使用License.setLicenseKey()设置有效许可证密钥,以及拥有带密码的PFX或P12证书文件。

Darrius Serrant
全栈软件工程师(WebOps)

Darrius Serrant 拥有迈阿密大学的计算机科学学士学位,目前在 Iron Software 担任全栈 WebOps 市场工程师。从小就被编码吸引,他认为计算机既神秘又易于接触,使其成为创意和问题解决的理想媒介。

在 Iron Software,Darrius 喜欢创造新事物,并简化复杂概念以使其更易理解。作为我们常驻的开发者之一,他还自愿教授学生,与下一代分享他的专业知识。

对于 Darrius 来说,他的工作令人满意,因为它被重视并产生真正的影响。

准备开始了吗?
版本: 2026.5 just released
Still Scrolling Icon

还在滚动吗?

想快速获得证据?
运行示例看着你的HTML代码变成PDF文件。