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

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

在Java中使用IronPDF对PDF进行数字签名,让您可以应用加密签名,以验证文档的真实性并检测未授权的更改。 IronPDF支持PdfCertificationLevel控制PDF认证级别,并连接到时间戳权威服务器以确保长期签名有效性。

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

  1. 通过Maven或Gradle安装IronPDF for Java
  2. 使用License.setLicenseKey()设置您的许可证密钥
  3. 使用PdfDocument.fromFile()加载PDF
  4. 使用您的PFX证书文件和密码创建PdfSignature
  5. 使用signDigitalSignature()应用签名
  6. 使用saveAs()保存签名的PDF
 :title=Quickstart
//:path=/static-assets/ironpdf-java/content-code-examples/how-to/how-to-digitally-sign-pdfs-java-tutorial/quickstart.java
import 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 {
        // Set the IronPDF license key
        License.setLicenseKey("IRONPDF-MYLICENSE-KEY-1EF01");

        // Load an existing PDF document
        PdfDocument pdf = PdfDocument.fromFile(Path.of("document.pdf"));

        // Create a PdfSignature using a PFX certificate file and its password
        PdfSignature signature = new PdfSignature("certificate.pfx", "password123");

        // Set signature metadata for audit trails
        signature.setSigningContact("John Smith");
        signature.setSigningLocation("New York");
        signature.setSigningReason("Document Approval");

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

        // Save the signed PDF to a new file
        pdf.saveAs(Path.of("signed.pdf"));
    }
}
 :title=Quickstart
//:path=/static-assets/ironpdf-java/content-code-examples/how-to/how-to-digitally-sign-pdfs-java-tutorial/quickstart.java
import 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 {
        // Set the IronPDF license key
        License.setLicenseKey("IRONPDF-MYLICENSE-KEY-1EF01");

        // Load an existing PDF document
        PdfDocument pdf = PdfDocument.fromFile(Path.of("document.pdf"));

        // Create a PdfSignature using a PFX certificate file and its password
        PdfSignature signature = new PdfSignature("certificate.pfx", "password123");

        // Set signature metadata for audit trails
        signature.setSigningContact("John Smith");
        signature.setSigningLocation("New York");
        signature.setSigningReason("Document Approval");

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

        // Save the signed PDF to a new file
        pdf.saveAs(Path.of("signed.pdf"));
    }
}
JAVA

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

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

IronPDF通过围绕PdfDocument构建的一致API处理这两种签名类型。 有关初始设置、依赖项配置和许可证密钥说明,请参阅入门概览

开始之前我需要什么?

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

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

有关完整的依赖项设置和项目配置,请参阅入门概览

如何为PDF应用数字签名?

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

  • setSigningContact(String):签署人的姓名或电子邮件
  • setSigningLocation(String):签署人的物理或组织位置
  • setSigningReason(String):简短说明文件签名的原因

这些字段显示在PDF查看器的签名属性面板中,为合规目的创建了有用的审计记录。 在加载的saveAs()保存结果。

//:path=/static-assets/ironpdf-java/content-code-examples/how-to/how-to-digitally-sign-pdfs-java-tutorial/apply-signature.java
import 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 {
        // Set the IronPDF license key
        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"));
    }
}
//:path=/static-assets/ironpdf-java/content-code-examples/how-to/how-to-digitally-sign-pdfs-java-tutorial/apply-signature.java
import 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 {
        // Set the IronPDF license key
        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"));
    }
}
JAVA

signDigitalSignature()完成后,PDF包含用PFX文件的私钥签署的文档内容的加密哈希。此点之后对文件的任何修改都会使签名无效。

Icon Quote related to 如何为PDF应用数字签名?

我最喜欢的这种库是 IronPDF。它允许快速高效地操作 PDF 文件。它还具有许多有价值的功能,比如导出为 PDF/A 格式和数字签名 PDF 文档。

Milan Jovanovic related to 如何为PDF应用数字签名?

Milan Jovanovic

微软MVP

查看案例研究
Icon Quote related to 如何为PDF应用数字签名?

IronOCR 意味着我们每年可以节省 $40,000 的人工处理成本,同时提高生产力,并释放资源用于高影响任务。我强烈推荐它。

Brent Matzelle related to 如何为PDF应用数字签名?

Brent Matzelle

首席技术官,OPYN

查看案例研究
Icon Quote related to 如何为PDF应用数字签名?

Iron Suite 在我们的运营中起着至关重要的作用。这些工具提高了业务各方面的效率,包括创建平面图和改善库存管理。

David Jones related to 如何为PDF应用数字签名?

David Jones

首席软件工程师,Agorus Build

查看案例研究

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

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

要添加可见图像,请将图像文件作为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;
import 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 {
        // Set the IronPDF license key
        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;
import 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 {
        // Set the IronPDF license key
        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
import 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 {
        // Set the IronPDF license key
        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
import 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 {
        // Set the IronPDF license key
        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_FILLING_AND_ANNOTATIONS

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

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

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

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

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

//:path=/static-assets/ironpdf-java/content-code-examples/how-to/how-to-digitally-sign-pdfs-java-tutorial/timestamp-signature.java
import 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 {
        // Set the IronPDF license key
        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
import 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 {
        // Set the IronPDF license key
        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的下一步是什么?

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.6 刚刚发布
Still Scrolling Icon

还在滚动吗?

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