验证 PDF 中的数字签名是确定文档未被篡改,并且确实由声明的签署者签署的关键步骤。这一验证过程对于保持文档的完整性和可信度至关重要。同时,提取数字签名可以让你获取签名的详细信息,包括签名图片和数字证书信息等,这些信息对于后续的验证和归档工作非常重要。这篇文章将介绍如何使用 Spire.PDF for Java 和 Java 验证或提取 PDF 中的数字签名。
安装 Spire.PDF for Java
首先,您需要在 Java 程序中添加 Spire.Pdf.jar 文件作为依赖项。JAR 文件可以从此链接下载。如果您使用 Maven,则可以将以下代码添加到项目的 pom.xml 文件中,从而在应用程序中导入 JAR 文件。
<repositories>
<repository>
<id>com.e-iceblue</id>
<name>e-iceblue</name>
<url>https://repo.e-iceblue.cn/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.pdf</artifactId>
<version>10.10.7</version>
</dependency>
</dependencies>
Java 验证 PDF 数字签名
Spire.PDF for Java 提供了 PdfSignature.verifySignature() 方法,用于检查 PDF 文档中数字签名的有效性。详细步骤如下:
- 创建 PdfDocument 类的对象。
- 使用 PdfDocument.LoadFromFile() 方法加载 PDF 文档。
- 使用 PdfDocument.Form 属性获取 PDF 文档的表单。
- 遍历表单中的所有域,找到签名域。
- 使用 PdfSignatureFieldWidget.getSignature() 方法获取签名。
- 使用 PdfSignature.verifySignature() 方法验证签名的有效性。
- Java
import com.spire.pdf.PdfDocument;
import com.spire.pdf.fields.PdfField;
import com.spire.pdf.security.PdfSignature;
import com.spire.pdf.widget.PdfFormWidget;
import com.spire.pdf.widget.PdfSignatureFieldWidget;
public class VerifySignature {
public static void main(String[] args) {
// 创建 PdfDocument 对象
PdfDocument pdf = new PdfDocument();
// 加载 PDF 文档
pdf.loadFromFile("签名.pdf");
// 获取 PDF 文档的表单
PdfFormWidget formWidget = (PdfFormWidget) pdf.getForm();
if (formWidget.getFieldsWidget().getCount() > 0) {
// 遍历表单中的所有域
for (int i = 0; i < formWidget.getFieldsWidget().getCount(); i++) {
PdfField field = formWidget.getFieldsWidget().get(i);
// 查找签名域
if (field instanceof PdfSignatureFieldWidget) {
PdfSignatureFieldWidget signatureField = (PdfSignatureFieldWidget) field;
// 获取签名
PdfSignature signature = signatureField.getSignature();
// 验证签名
boolean valid = signature.verifySignature();
if (valid) {
System.out.print("签名有效!");
} else {
System.out.print("签名无效!");
}
}
}
}
}
}
Java 检查已签名的 PDF 是否被修改
要验证已签名的 PDF 文档是否被修改,你可以使用 PdfSignature.VerifyDocModified() 方法。详细步骤如下:
- 创建 PdfDocument 类的对象。
- 使用 PdfDocument.LoadFromFile() 方法加载 PDF 文档。
- 使用 PdfDocument.Form 属性获取 PDF 文档的表单。
- 遍历表单中的所有域,找到签名域。
- 使用 PdfSignatureFieldWidget.getSignature() 方法获取签名。
- 使用 PdfSignature.VerifyDocModified() 方法检查文档自签署以来是否已被修改。
- Java
import com.spire.pdf.PdfDocument;
import com.spire.pdf.fields.PdfField;
import com.spire.pdf.security.PdfSignature;
import com.spire.pdf.widget.PdfFormWidget;
import com.spire.pdf.widget.PdfSignatureFieldWidget;
public class CheckIfSignedPdfIsModified {
public static void main(String[] args) {
// 创建 PdfDocument 对象
PdfDocument pdf = new PdfDocument();
// 加载 PDF 文档
pdf.loadFromFile("签名.pdf");
// 获取 PDF 文档的表单
PdfFormWidget formWidget = (PdfFormWidget) pdf.getForm();
if (formWidget.getFieldsWidget().getCount() > 0) {
// 遍历表单中的所有域
for (int i = 0; i < formWidget.getFieldsWidget().getCount(); i++) {
PdfField field = formWidget.getFieldsWidget().get(i);
// 查找签名域
if (field instanceof PdfSignatureFieldWidget) {
PdfSignatureFieldWidget signatureField = (PdfSignatureFieldWidget) field;
// 获取签名
PdfSignature signature = signatureField.getSignature();
// 验证签名
boolean modified = signature.verifyDocModified();
if (modified) {
System.out.print("文档已被修改!");
} else {
System.out.print("文档未被修改!");
}
}
}
}
}
}
Java 从 PDF 中提取签名图片和数字证书信息
你可以使用 PdfFormWidget.extractSignatureAsImages() 和 PdfSignature.getCertificate().toString() 方法从 PDF 中提取签名图片和数字证书信息。详细步骤如下:
- 创建 PdfDocument 类的对象。
- 使用 PdfDocument.LoadFromFile() 方法加载 PDF 文档。
- 使用 PdfDocument.Form 属性获取 PDF 文档的表单。
- 使用 PdfFormWidget.extractSignatureAsImages() 方法提取签名图片,然后将每个图片保存到文件。
- 遍历表单中的所有域,找到签名域。
- 使用 PdfSignatureFieldWidget.getSignature() 方法获取签名。
- 使用 PdfSignature.getCertificate().toString() 方法获取签名的数字证书信息。
- Java
import com.spire.pdf.PdfDocument;
import com.spire.pdf.fields.PdfField;
import com.spire.pdf.security.PdfSignature;
import com.spire.pdf.widget.PdfFormWidget;
import com.spire.pdf.widget.PdfSignatureFieldWidget;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class ExtractSignatureImage {
public static void main(String[] args) {
// 创建 PdfDocument 对象
PdfDocument pdf = new PdfDocument();
// 加载 PDF 文档
pdf.loadFromFile("签名.pdf");
// 获取 PDF 文档的表单
PdfFormWidget formWidget = (PdfFormWidget) pdf.getForm();
// 提取签名图片
Image[] images = formWidget.extractSignatureAsImages();
// 遍历图片并将每个图片保存到文件
for (int i = 0; i < images.length; i++) {
try {
// 将 Image 转换为 BufferedImage
BufferedImage bufferedImage = (BufferedImage) images[i];
// 指定输出文件路径
File outputFile = new File("output\\签名_" + i + ".png");
// 将图片保存为 PNG 文件
ImageIO.write(bufferedImage, "png", outputFile);
} catch (IOException e) {
e.printStackTrace();
}
}
// 创建文本文件以保存数字证书信息
try (BufferedWriter writer = new BufferedWriter(new FileWriter("output\\数字证书信息.txt"))) {
if (formWidget.getFieldsWidget().getCount() > 0) {
// 遍历表单中的所有域
for (int i = 0; i < formWidget.getFieldsWidget().getCount(); i++) {
PdfField field = formWidget.getFieldsWidget().get(i);
// 查找签名域
if (field instanceof PdfSignatureFieldWidget) {
PdfSignatureFieldWidget signatureField = (PdfSignatureFieldWidget) field;
// 获取签名
PdfSignature signature = signatureField.getSignature();
// 获取签名的数字证书信息
String certificateInfo = signature.getCertificate() != null ? signature.getCertificate().toString() : "没有证书";
// 将数字证书信息写入文本文件
writer.write("数字证书信息: \n" + certificateInfo);
writer.write("-----------------------------------\n");
}
}
} else {
writer.write("未找到签名域。");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
申请临时 License
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。