用Java验证pdf文件的电子章签名

网友投稿 283 2023-02-11

用Java验证pdf文件的电子章签名

pom.xml

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

com.yalong

verifyPdf

1.0-SNAPSHOT

UTF-8

1.8

1.18.10

javax.xml.bind

jaxb-api

2.3.0

e-iceblue

spire.pdf.free

2.6.3

org.apache.poi

poi

4.0.1

org.apache.poi

poi-ooxml

4.0.1

org.projectlombok

lombok

${lombok.version}

com.e-iceblue

http://repo.e-iceblue.cn/repository/maven-public/

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

com.yalong

verifyPdf

1.0-SNAPSHOT

UTF-8

1.8

1.18.10

javax.xml.bind

jaxb-api

2.3.0

e-iceblue

spire.pdf.free

2.6.3

org.apache.poi

poi

4.0.1

org.apache.poi

poi-ooxml

4.0.1

org.projectlombok

lombok

${lombok.version}

com.e-iceblue

http://repo.e-iceblue.cn/repository/maven-public/

VerifySignature.java

import com.spire.pdf.PdfDocument;

import com.spire.pdf.security.PdfCertificate;

import com.spire.pdf.security.PdfSignature;

import com.spire.pdf.widget.PdfFormFieldWidgetCollection;

import com.spire.pdf.widget.PdfFormWidget;

import com.spire.pdf.widget.PdfSignatureFieldWidget;

import lombok.Data;

import lombok.ToString;

import org.apache.poi.ss.usermodel.*;

import org.apache.poi.ss.usermodel.Font;

import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.Serializable;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Date;

import java.util.HashSet;

import java.util.List;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

import javax.swing.*;

import java.awt.*;

@Data

@ToString

class ExcelDataVO implements Serializable {

private String fileName;

private String signDate;

private String validBefore;

private String validAfter;

private String subject;

private String serialNumber;

private Boolean isEffective = false;

}

class ExcelWriter {

//表头

private static final ListpvHMC CELL_HEADS;

static {

// 类装载时就载入指定好的表头信息,如有需要,可以考虑做成动态生成的表头

CELL_HEADS = new ArrayList<>();

CELL_HEADS.add("文件名");

CELL_HEADS.add("签名时间");

CELL_HEADS.add("有效期");

CELL_HEADS.add("有效期");

CELL_HEADS.add("签名机构");

CELL_HEADS.add("序列号");

CELL_HEADS.add("是否通过验签");

}

/**

* 生成Excel并写入数据信息

*

* @param dataList 数据列表

* @return 写入数据后的工作簿对象

*/

public static Workbook exportData(List dataList) {

// 生成xlsx的Excel

Workbook workbook = new SXSSFWorkbook();

// 如需生成xls的Excel,请使用下面的工作簿对象,注意后续输出时文件后缀名也需更改为xls

//Workbook workbook = new HSSFWorkbook();

// 生成Sheet表,写入第一行的表头

Sheet sheet = buildDataSheet(workbook);

//构建每行的数据内容

int rowNum = 1;

for (ExcelDataVO data : dataList) {

if (data == null) {

continue;

}

//输出行数据

Row row = sheet.createRow(rowNum++);

convertDataToRow(workbook, data, row);

}

return workbook;

}

/**

* 生成sheet表,并写入第一行数据(表头)

*

* @param workbook 工作簿对象

* @return 已经写入表头的Sheet

*/

private static Sheet buildDataSheet(Workbook workbook) {

Sheet sheet = workbook.createSheet();

// 设置表头宽度

for (int i = 0; i < CELL_HEADS.size(); i++) {

sheet.setColumnWidth(i, 4000);

}

// 设置默认行高

sheet.setDefaultRowHeight((short) 400);

// 构建头单元格样式

CellStyle cellStyle = buildHeadCellStyle(sheet.getWorkbook());

// 写入第一行各列的数据

Row head = sheet.createRow(0);

for (int i = 0; i < CELL_HEADS.size(); i++) {

Cell cell = head.createCell(i);

cell.setCellValue(CELL_HEADS.get(i));

cell.setCellStyle(cellStyle);

}

return sheet;

}

/**

* 设置第一行表头的样式

*

* @param workbook 工作簿对象

* @return 单元格样式对象

*/

private static CellStyle buildHeadCellStyle(Workbook workbook) {

CellStyle style = workbook.createCellStyle();

//对齐方式设置

style.setAlignment(HorizontalAlignment.CENTER);

//边框颜色和宽度设置

style.setBorderBottom(BorderStyle.THIN);

style.setBottomBorderColor(IndexedColors.BLACK.getIndex()); // 下边框

style.setBorderLeft(BorderStyle.THIN);

style.setLeftBorderColor(IndexedColors.BLACK.getIndex()); // 左边框

style.setBorderRight(BorderStyle.THIN);

style.setRightBorderColor(IndexedColors.BLACK.getIndex()); // 右边框

style.setBorderTop(BorderStyle.THIN);

style.setTopBorderColor(IndexedColors.BLACK.getIndex()); // 上边框

//设置背景颜色

style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());

style.setFillPattern(FillPatternType.SOLID_FOREGROUND);

//粗体字设置

Font font = workbook.createFont();

font.setBold(true);

style.setFont(font);

return style;

}

/**

* 将数据转换成行

*

* @param data 源数据

* @param row 行对象

*/

private static void convertDataToRow(Workbook workbook, ExcelDataVO data, Row row) {

int cellNum = 0;

Cell cell;

//对特殊数值设置颜色

CellStyle cellStyle = workbook.createCellStyle();

//字体设置

Font font = workbook.createFont();

font.setBold(true);

font.setColor(IndexedColors.GREEN.getIndex());

cellStyle.setFont(font);

// 文件名

cell = row.createCell(cellNum++);

cell.setCellValue(data.getFileName());

// 签名时间

cell = row.createCell(cellNum++);

cell.setCellValue(null == data.getSignDate() ? "" : data.getSignDate());

// 有效期

cell = row.createCell(cellNum++);

cell.setCellValue(null == data.getValidBefore() ? "" : data.getValidBefore());

// 有效期

cell = row.createCell(cellNum++);

cell.setCellValue(null == data.getValidAfter() ? "" : data.getValidAfter());

//主题

cell = row.createCell(cellNum++);

cell.setCellValue(null == data.getSubject() ? "" : data.getSubject());

//序列号

cell = row.createCell(cellNum++);

cell.setCellValue(null == data.getSerialNumber() ? "" : data.getSerialNumber());

//是否通过验签

cell = row.createCell(cellNum);

if (data.getIsEffective()) {

cell.setCellValue("签名有效");

} else {

cell.setCellValue("签名无效");

cell.setCellStyle(cellStyle);

}

}

public static void writeExcel(List dataVOList, String exportFilePath) {

// 写入数据到工作簿对象内

Workbook workbook = ExcelWriter.exportData(dataVOList);

// 以文件的形式输出工作簿对象

FileOutputStream fileOut = null;

try {

File exportFile = new File(exportFilePath);

if (!exportFile.exists()) {

boolean newFile = exportFile.createNewFile();

if (!newFile) {

System.out.println("文件创建失败");

}

}

fileOut = new FileOutputStream(exportFilePath);

workbook.write(fileOut);

fileOut.flush();

} catch (Exception e) {

System.out.println("输出Excel时发生错误,错误原因:" + e.getMessage());

} finally {

try {

if (null != fileOut) {

fileOut.close();

}

workbook.close();

} catch (IOException e) {

System.out.println("关闭输出流时发生错误,错误原因:" + e.getMessage());

}

}

}

}

public class VerifySignature {

private static String fromDirPath;

private static String toFilePath;

public static void main(String[] args) {

final JFrame jf = new JFrame("测试窗口");

jf.setSize(400, 250);

jf.setLocationRelativeTo(null);

jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

JPanel panel = new JPanel();

// 创建文本区域, 用于显示相关信息

final JTextArea msgTextArea = new JTextArea(10, 30);

msgTextArea.setLineWrap(true);

panel.add(msgTextArea);

JButton openBtn = new JButton("选择文件路径");

openBtn.addActionListener(e -> showFileOpenDialog(jf, msgTextArea));

panel.add(openBtn);

JButton saveBtn = new JButton("结果保存位置");

saveBtn.addActionListener(e -> showFileSaveDialog(jf, msgTextArea));

panel.add(saveBtn);

jf.setContentPane(panel);

jf.setVisible(true);

JButton enSureBtn = new JButton("确认");

enSureBtn.addActionListener(e -> enSureListener(jf));

panel.add(enSureBtn);

jf.setContentPane(panel);

jf.setVisible(true);

}

/*

* 打开文件

*/

private static void showFileOpenDialog(Component parent, JTextArea msgTextArea) {

// 创建一个默认的文件选取器

JFileChooser fileChooser = new JFileChooser();

// 设置默认显示的文件夹为当前文件夹

fileChooser.setCurrentDirectory(new File("."));

// 设置文件选择的模式(只选文件、只选文件夹、文件和文件均可选)

fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

// 设置是否允许多选

fileChooser.setMultiSelectionEnabled(false);

// // 添加可用的文件过滤器(FileNameExtensionFilter 的第一个参数是描述, 后面是需要过滤的文件扩展名 可变参数)

// fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("zip(*.zip, *.rar)", "zip", "rar"));

//

// // 设置默认使用的文件过滤器

// fileChooser.setFileFilter(new FileNameExtensionFilter("image(*.jpg, *.png, *.gif)", "jpg", "png", "gif"));

// 打开文件选择框(线程将被阻塞, 直到选择框被关闭)

int result = fileChooser.showOpenDialog(parent);

if (result == JFileChooser.APPROVE_OPTION) {

// 如果点击了"确定", 则获取选择的文件路径

File file = fileChooser.getSelectedFile();

fromDirPath = file.getAbsolutePath();

msgTextArea.append("选择源文件: " + fromDirPath + "\n\n");

}

}

/*

* 选择文件保存路径

*/

private static void showFileSaveDialog(Component parent, JTextArea msgTextArea) {

// 创建一个默认的文件选取器

JFileChooser fileChooser = new JFileChooser();

//把时间戳经过处理得到期望格式的时间

Date date = new Date();

SimpleDateFormat format0 = new SimpleDateFormat("yyyyMMddHHmmss");

String now = format0.format(date.getTime());

// 设置打开文件选择框后默认输入的文件名

fileChooser.setSelectedFile(new File(now + ".xlsx"));

// 打开文件选择框(线程将被阻塞, 直到选择框被关闭)

int result = fileChooser.showSaveDialog(parent);

if (result == JFileChooser.APPROVE_OPTION) {

// 如果点击了"保存", 则获取选择的保存路径

File file = fileChooser.getSelectedFile();

toFilePath = file.getAbsolutePath();

msgTextArea.append("结果文件路径: " + toFilePath + "\n\n");

}

}

//找到需要的内容

public final static Pattern pattern = Pattern.compile("\\[Subject\\].*?O=(.*?),.*?\\[Issuer\\](.*?)\\[Serial Number\\](.*?)\\[Not Before\\](.*?)\\[Not After\\](.*?)\\[Thumbprint\\](.*?)");

// 剔除特殊字符

public final static Pattern replacePattern = Pattern.compile("\t|\r|\n");

/**

* 查找某个路径下的所有pdf文件

*

* @return 所有的pdf绝对路径

*/

public static HashSet listDir(String path) {

HashSet FileNameString = new HashSet();

File file = new File(path); //获取其file对象

File[] fs = file.listFiles(); //遍历path下的文件和目录,放在File数组中

if (fs == null) {

System.out.println(path + "路径下没有文件");

return null;

}

//遍历File[]数组

for (File f : fs) {

String fileName = String.valueOf(f);

if (!f.isDirectory() && fileName.toLowerCase().endsWith(".pdf")) //若非目录(即文件),则打印

FileNameString.add(fileName);

}

return FileNameString;

}

/**

* 检验pdf文件是否签名

*

* @param filePath pdf文件绝对路径

*/

public static ExcelDataVO checkPdf(String filePath) {

//创建PdfDocument实例

PdfDocument doc = new PdfDocument();

//创建结果集

ExcelDataVO excelDataVO = new ExcelDataVO();

//文件名,注意windows下应该是\\,linux下是/

String fileName = filePath.substring(filePath.lastIndexOf("\\") + 1);

excelDataVO.setFileName(fileName);

//加载含有签名的PDF文件

doc.loadFromFile(filePath);

//获取域集合

PdfFormWidget pdfFormWidget = (PdfFormWidget) doc.getForm();

PdfFormFieldWidgetCollection pdfFormFieldWidgetCollection = pdfFormWidget.getFieldsWidget();

// int countCollection = pdfFormFieldWidgetCollection.getCount();

// System.out.println("共发现" + countCollection + "个域");

//遍历域

for (int i = 0; i < pdfFormFieldWidgetCollection.getCount(); i++) {

//判定是否为签名域

if (pdfFormFieldWidgetCollection.get(i) instanceof PdfSignatureFieldWidget) {

//获取签名域

PdfSignatureFieldWidget signatureFieldWidget = (PdfSignatureFieldWidget) pdfFormFieldWidgetCollection.get(i);

//获取签名时间

PdfSignature signature = signatureFieldWidget.getSignature();

excelDataVO.setSignDate(String.valueOf(signature.getDate()));

//获取签名的内容

PdfCertificate certificate = signature.getCertificate();

// System.out.println("Issuer:" + certificate.getIssuer());

// System.out.println("Subject:" + certificate.getSubject());

// System.out.println("---------");

// excelDataVO.setSubject(String.valueOf(certificate.getSubject()));

String certificateString = certificate.toString();

Matcher m = replacePattern.matcher(certificateString);

certificateString = m.replaceAll("");

Matcher matcher = pattern.matcher(certificateString);

while (matcher.find()) {

// String group = matcher.group(0);

String subject = matcher.group(1pvHMC);

// String issuer = matcher.group(2);

String serialNumber = matcher.group(3);

String before = matcher.group(4);

String after = matcher.group(5);

// String sha1 = matcher.group(6);

excelDataVO.setSubject(subject);

excelDataVO.setSerialNumber(serialNumber);

excelDataVO.setValidBefore(before);

excelDataVO.setValidAfter(after);

}

//判定签名是否有效

boolean result = signature.verifySignature();

excelDataVO.setIsEffective(result);

if (result) {

return excelDataVO;

}

}

}

return excelDataVO;

}

/*

* 开始执行业务逻辑

*/

private static void enSureListener(JFrame parent) {

parent.dispose();

System.out.println("开始验签...");

//从某个路径下获取所有的pdf文件路径

HashSet filePaths = listDir(fromDirPath);

if (filePaths == null) {

return;

}

List excelDataVOS = new ArrayList<>();

for (String filePath : filePaths) {

ExcelDataVO excelDataVO = checkPdf(filePath);

excelDataVOS.add(excelDataVO);

}

ExcelWriter.writeExcel(excelDataVOS, toFilePath);

System.out.println("验签完成...");

}

}

以上就是用Java验证pdf文件的电子章签名的详细内容,更多关于Java验证pdf文件的电子章签名的资料请关注我们其它相关文章!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:聚合数据网站制作(聚合客户端)
下一篇:spring中使用mybatis plus连接sqlserver的方法实现
相关文章

 发表评论

暂时没有评论,来抢沙发吧~