欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

用Java驗證pdf文件的電子章簽名

 更新時間:2020年12月28日 11:55:16   作者:rm-rf*  
這篇文章主要介紹了如何用Java驗證pdf文件的電子章簽名,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.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">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.yalong</groupId>
  <artifactId>verifyPdf</artifactId>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
    <lombok.version>1.18.10</lombok.version>

  </properties>
  <dependencies>
    <!--    <dependency>-->
    <!--      <groupId> e-iceblue </groupId>-->
    <!--      <artifactId>spire.pdf</artifactId>-->
    <!--      <version>3.4.2</version>-->
    <!--    </dependency>-->
    <dependency>
      <groupId>javax.xml.bind</groupId>
      <artifactId>jaxb-api</artifactId>
      <version>2.3.0</version>
    </dependency>
    <dependency>
      <groupId>e-iceblue</groupId>
      <artifactId>spire.pdf.free</artifactId>
      <version>2.6.3</version>
    </dependency>

    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>4.0.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>4.0.1</version>
    </dependency>
    <!--lombok-->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>${lombok.version}</version>
    </dependency>
  </dependencies>

  <repositories>
    <repository>
      <id>com.e-iceblue</id>
      <url>http://repo.e-iceblue.cn/repository/maven-public/</url>
    </repository>
  </repositories>
</project>

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 List<String> CELL_HEADS;

  static {
    // 類裝載時就載入指定好的表頭信息,如有需要,可以考慮做成動態(tài)生成的表頭
    CELL_HEADS = new ArrayList<>();
    CELL_HEADS.add("文件名");
    CELL_HEADS.add("簽名時間");
    CELL_HEADS.add("有效期");
    CELL_HEADS.add("有效期");
    CELL_HEADS.add("簽名機構(gòu)");
    CELL_HEADS.add("序列號");
    CELL_HEADS.add("是否通過驗簽");
  }

  /**
   * 生成Excel并寫入數(shù)據(jù)信息
   *
   * @param dataList 數(shù)據(jù)列表
   * @return 寫入數(shù)據(jù)后的工作簿對象
   */
  public static Workbook exportData(List<ExcelDataVO> dataList) {
    // 生成xlsx的Excel
    Workbook workbook = new SXSSFWorkbook();

    // 如需生成xls的Excel,請使用下面的工作簿對象,注意后續(xù)輸出時文件后綴名也需更改為xls
    //Workbook workbook = new HSSFWorkbook();

    // 生成Sheet表,寫入第一行的表頭
    Sheet sheet = buildDataSheet(workbook);
    //構(gòu)建每行的數(shù)據(jù)內(nèi)容
    int rowNum = 1;
    for (ExcelDataVO data : dataList) {
      if (data == null) {
        continue;
      }
      //輸出行數(shù)據(jù)
      Row row = sheet.createRow(rowNum++);
      convertDataToRow(workbook, data, row);
    }
    return workbook;
  }

  /**
   * 生成sheet表,并寫入第一行數(shù)據(jù)(表頭)
   *
   * @param workbook 工作簿對象
   * @return 已經(jīng)寫入表頭的Sheet
   */
  private static Sheet buildDataSheet(Workbook workbook) {
    Sheet sheet = workbook.createSheet();
    // 設(shè)置表頭寬度
    for (int i = 0; i < CELL_HEADS.size(); i++) {
      sheet.setColumnWidth(i, 4000);
    }
    // 設(shè)置默認行高
    sheet.setDefaultRowHeight((short) 400);
    // 構(gòu)建頭單元格樣式
    CellStyle cellStyle = buildHeadCellStyle(sheet.getWorkbook());
    // 寫入第一行各列的數(shù)據(jù)
    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;
  }

  /**
   * 設(shè)置第一行表頭的樣式
   *
   * @param workbook 工作簿對象
   * @return 單元格樣式對象
   */
  private static CellStyle buildHeadCellStyle(Workbook workbook) {
    CellStyle style = workbook.createCellStyle();
    //對齊方式設(shè)置
    style.setAlignment(HorizontalAlignment.CENTER);
    //邊框顏色和寬度設(shè)置
    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()); // 上邊框
    //設(shè)置背景顏色
    style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
    style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
    //粗體字設(shè)置
    Font font = workbook.createFont();
    font.setBold(true);
    style.setFont(font);
    return style;
  }


  /**
   * 將數(shù)據(jù)轉(zhuǎn)換成行
   *
   * @param data 源數(shù)據(jù)
   * @param row 行對象
   */
  private static void convertDataToRow(Workbook workbook, ExcelDataVO data, Row row) {

    int cellNum = 0;
    Cell cell;

    //對特殊數(shù)值設(shè)置顏色
    CellStyle cellStyle = workbook.createCellStyle();

    //字體設(shè)置
    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<ExcelDataVO> dataVOList, String exportFilePath) {


    // 寫入數(shù)據(jù)到工作簿對象內(nèi)
    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("文件創(chuàng)建失敗");
        }
      }

      fileOut = new FileOutputStream(exportFilePath);
      workbook.write(fileOut);
      fileOut.flush();
    } catch (Exception e) {
      System.out.println("輸出Excel時發(fā)生錯誤,錯誤原因:" + e.getMessage());
    } finally {
      try {
        if (null != fileOut) {
          fileOut.close();
        }
        workbook.close();
      } catch (IOException e) {
        System.out.println("關(guān)閉輸出流時發(fā)生錯誤,錯誤原因:" + 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();

    // 創(chuàng)建文本區(qū)域, 用于顯示相關(guān)信息
    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("結(jié)果保存位置");
    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) {
    // 創(chuàng)建一個默認的文件選取器
    JFileChooser fileChooser = new JFileChooser();

    // 設(shè)置默認顯示的文件夾為當(dāng)前文件夾
    fileChooser.setCurrentDirectory(new File("."));

    // 設(shè)置文件選擇的模式(只選文件、只選文件夾、文件和文件均可選)
    fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

    // 設(shè)置是否允許多選
    fileChooser.setMultiSelectionEnabled(false);

//    // 添加可用的文件過濾器(FileNameExtensionFilter 的第一個參數(shù)是描述, 后面是需要過濾的文件擴展名 可變參數(shù))
//    fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("zip(*.zip, *.rar)", "zip", "rar"));
//
//    // 設(shè)置默認使用的文件過濾器
//    fileChooser.setFileFilter(new FileNameExtensionFilter("image(*.jpg, *.png, *.gif)", "jpg", "png", "gif"));

    // 打開文件選擇框(線程將被阻塞, 直到選擇框被關(guān)閉)
    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) {
    // 創(chuàng)建一個默認的文件選取器
    JFileChooser fileChooser = new JFileChooser();

    //把時間戳經(jīng)過處理得到期望格式的時間
    Date date = new Date();
    SimpleDateFormat format0 = new SimpleDateFormat("yyyyMMddHHmmss");
    String now = format0.format(date.getTime());

    // 設(shè)置打開文件選擇框后默認輸入的文件名
    fileChooser.setSelectedFile(new File(now + ".xlsx"));

    // 打開文件選擇框(線程將被阻塞, 直到選擇框被關(guān)閉)
    int result = fileChooser.showSaveDialog(parent);

    if (result == JFileChooser.APPROVE_OPTION) {
      // 如果點擊了"保存", 則獲取選擇的保存路徑
      File file = fileChooser.getSelectedFile();
      toFilePath = file.getAbsolutePath();
      msgTextArea.append("結(jié)果文件路徑: " + toFilePath + "\n\n");
    }
  }

  //找到需要的內(nèi)容
  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<String> listDir(String path) {
    HashSet<String> FileNameString = new HashSet<String>();
    File file = new File(path);    //獲取其file對象
    File[] fs = file.listFiles();  //遍歷path下的文件和目錄,放在File數(shù)組中
    if (fs == null) {
      System.out.println(path + "路徑下沒有文件");
      return null;
    }

    //遍歷File[]數(shù)組
    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) {
    //創(chuàng)建PdfDocument實例
    PdfDocument doc = new PdfDocument();

    //創(chuàng)建結(jié)果集
    ExcelDataVO excelDataVO = new ExcelDataVO();

    //文件名,注意windows下應(yīng)該是\\,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("共發(fā)現(xiàn)" + 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()));

        //獲取簽名的內(nèi)容
        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(1);
//          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;
  }

  /*
   * 開始執(zhí)行業(yè)務(wù)邏輯
   */
  private static void enSureListener(JFrame parent) {
    parent.dispose();
    System.out.println("開始驗簽...");

    //從某個路徑下獲取所有的pdf文件路徑
    HashSet<String> filePaths = listDir(fromDirPath);
    if (filePaths == null) {
      return;
    }
    List<ExcelDataVO> excelDataVOS = new ArrayList<>();

    for (String filePath : filePaths) {
      ExcelDataVO excelDataVO = checkPdf(filePath);
      excelDataVOS.add(excelDataVO);
    }

    ExcelWriter.writeExcel(excelDataVOS, toFilePath);
    System.out.println("驗簽完成...");

  }

}

以上就是用Java驗證pdf文件的電子章簽名的詳細內(nèi)容,更多關(guān)于Java驗證pdf文件的電子章簽名的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java學(xué)習(xí)之一維數(shù)組中重復(fù)元素的去除

    java學(xué)習(xí)之一維數(shù)組中重復(fù)元素的去除

    關(guān)于一維數(shù)組中有重復(fù)的元素該怎么剔除,作為java初學(xué)者的我整理出不調(diào)用任何特殊庫的基礎(chǔ)方法,這種思想在其他語言也適用,有需要的朋友可以借鑒參考下
    2021-09-09
  • java使用淘寶API讀寫json實現(xiàn)手機歸屬地查詢功能代碼

    java使用淘寶API讀寫json實現(xiàn)手機歸屬地查詢功能代碼

    本文介紹java使用淘寶API讀寫json實現(xiàn)手機歸屬地查詢功能,代碼簡單,大家可以參考使用
    2013-11-11
  • Java如何手動創(chuàng)建線程池

    Java如何手動創(chuàng)建線程池

    這篇文章主要介紹了Java如何手動創(chuàng)建線程池,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • java中MultipartFile和File最簡單的互相轉(zhuǎn)換示例

    java中MultipartFile和File最簡單的互相轉(zhuǎn)換示例

    這篇文章主要給大家介紹了關(guān)于java中MultipartFile和File最簡單的互相轉(zhuǎn)換的相關(guān)資料,MultipartFile和File都是Java中用于處理文件上傳的類,MultipartFile用于處理上傳的文件,File用于處理本地磁盤上的文件,需要的朋友可以參考下
    2023-09-09
  • springmvc如何使用POJO作為參數(shù)

    springmvc如何使用POJO作為參數(shù)

    這篇文章主要介紹了springmvc如何使用POJO作為參數(shù),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • IDEA JavaWeb項目啟動運行后出現(xiàn)404錯誤的解決方法

    IDEA JavaWeb項目啟動運行后出現(xiàn)404錯誤的解決方法

    這篇文章主要介紹了IDEA JavaWeb項目啟動運行后出現(xiàn)404錯誤的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • 總結(jié)Java常用到的六個加密技術(shù)和代碼

    總結(jié)Java常用到的六個加密技術(shù)和代碼

    大家要記住現(xiàn)代密碼學(xué)最重要的原則柯克霍夫原則:數(shù)據(jù)的安全基于密鑰而不是算法的保密。也就是說即使密碼系統(tǒng)的任何細節(jié)已為人悉知,只要密匙未洩漏,它也應(yīng)是安全的。這篇文章給大家介紹了6個常用的加密技術(shù)和代碼。
    2016-07-07
  • 在Eclipse中運行Solr 基礎(chǔ)知識

    在Eclipse中運行Solr 基礎(chǔ)知識

    Solr我還是個菜鳥,寫這一些文章只是記錄一下最近一段時間學(xué)習(xí)Solr的心得,望各位同仁不要見笑,還希望多多指點
    2012-11-11
  • java基礎(chǔ)入門之IO流

    java基礎(chǔ)入門之IO流

    流是一種抽象概念,它代表了數(shù)據(jù)的無結(jié)構(gòu)化傳遞。。用來進行輸入輸出操作的流就稱為IO流。換句話說,IO流就是以流的方式進行輸入輸出
    2021-06-06
  • Java 并發(fā)編程的可見性、有序性和原子性

    Java 并發(fā)編程的可見性、有序性和原子性

    這篇文章主要介紹了Java 并發(fā)編程的可見性、有序性和原子性的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java并發(fā)編程,感興趣的朋友可以了解下。
    2020-11-11

最新評論