Pdf文件签名检查

如何检查pdf的签名

首先这里有一个已经签名的pdf文件,通过pdf软件可以看到文件的数字签名。
图1为签名后的文件,图2为签名后文件被篡改。
在这里插入图片描述
在这里插入图片描述

下面就是如何代码检查这里pdf文件的签名
1.引入依赖

 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf --><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13.3</version></dependency><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.70</version></dependency><dependency><groupId>org.bouncycastle</groupId><artifactId>bcpkix-jdk15on</artifactId><version>1.70</version></dependency>
  1. 编写检查签名的方法
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.security.PdfPKCS7;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.Principal;
import java.security.Provider;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.List;/*** pdf文件签名检查*/
public class PdfDigitalSignatureCheck {private static final Logger LOGGER = LoggerFactory.getLogger(PdfDigitalSignatureCheck.class);public static final boolean verifySignature(PdfReader pdfReader)throws GeneralSecurityException, IOException {boolean valid = false;AcroFields acroFields = pdfReader.getAcroFields();List<String> signatureNames = acroFields.getSignatureNames();if (!signatureNames.isEmpty()) {for (String name : signatureNames) {if (acroFields.signatureCoversWholeDocument(name)) {//设定签名提供者Provider provider=Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);if(provider==null){provider=new BouncyCastleProvider();Security.addProvider(provider);}PdfPKCS7 pkcs7 = acroFields.verifySignature(name);valid = pkcs7.verify();String reason = pkcs7.getReason();Calendar signedAt = pkcs7.getSignDate();X509Certificate signingCertificate = pkcs7.getSigningCertificate();Principal issuerDN = signingCertificate.getIssuerDN();Principal subjectDN = signingCertificate.getSubjectDN();LOGGER.info("valid = {}, date = {}, reason = '{}', issuer = '{}', subject = '{}'",valid, signedAt.getTime(), reason, issuerDN, subjectDN);break;}}}return valid;}/*** 验证签名** @param name* @return* @throws IOException* @throws GeneralSecurityException*/public static boolean validate(String name)throws IOException, GeneralSecurityException {PdfReader reader = new PdfReader(name);boolean isSign = verifySignature(reader);return isSign;}}
  1. 编写测试用例,并执行,可以看到数字证书相关信息。

如果有多个签名,则会显示多个签名

    @Testvoid pdfDigitalSignatureCheck() throws IOException, GeneralSecurityException {System.out.println("-----------数字签名检查------------");String[] files = {"D:\\test3\\test1_sign.pdf", "D:\\test3\\test1.pdf","D:\\test3\\test1_sign_wrapper.pdf"};for (String file : files) {boolean validate = PdfDigitalSignatureCheck.validate(file);log.info("{} 是否签名:{}", file, validate);}}

在这里插入图片描述

备注: test1_sign.pdf 为已签名文件,test1.pdf为原始未签名文件,test1_sign_wrapper.pdf为签名后更改过的文件(模拟签名后文件被篡改)

遇到的问题

签名设定

如果你的签入使用的BouncyCastleProvider,那么你的签名检查也应该使用BouncyCastleProvider,否则可能会报错。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/139008.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构——单链表

目录 一.前言 二.链表表示和实现&#xff08;单链表&#xff09; 1.1 顺序表的优缺点 1.2 链表的概念及结构 1.3 打印函数 1.4 空间函数 1.5 尾插函数&#xff08;最最最麻烦的&#xff09; 1.5.1 尾插最关键部分&#xff01; 1.6 头插函数 1.7 尾删函数…

云流化:XR扩展现实应用发展的一个新方向!

扩展现实的发展已经改变了我们工作、生活和娱乐的方式&#xff0c;而且这才刚刚开始。扩展现实 (Extended reality, XR) 涵盖了沉浸式技术&#xff0c;包括虚拟现实、增强现实和混合现实。从游戏到虚拟制作再到产品设计&#xff0c;XR 使人们能够以前所未有的方式在计算机生成的…

#循循渐进学51单片机#指针基础与1602液晶的初步认识#not.11

1、把本节课的指针相关内容&#xff0c;反复学习3到5遍&#xff0c;彻底弄懂指针是怎么回事&#xff0c;即使是死记硬背也要记住&#xff0c;等到后边用的时候可以实现顿悟。学会指针&#xff0c;就是突破了C语言的一道壁垒。 2&#xff0c;1602所有的指令功能都应用一遍&#…

vue3——pixi初学,编写一个简单的小游戏,复制粘贴可用学习

pixi官网 小游戏效果 两个文件夹 一个index.html 一个data.js //data.js import { reactive } from "vue"; import { Sprite, utils, Rectangle, Application, Text, Graphics } from "pixi.js";//首先 先创建一个舞台 export const app new Applicat…

[Go疑难杂症]为什么nil不等于nil

现象 在日常开发中&#xff0c;可能一不小心就会掉进 Go 语言的某些陷阱里&#xff0c;而本文要介绍的 nil ≠ nil 问题&#xff0c;便是其中一个&#xff0c;初看起来会让人觉得很诡异&#xff0c;摸不着头脑。 先来看个例子&#xff1a; type CustomizedError struct {Err…

【面试必刷TOP101】 删除有序链表中重复的元素-I 删除有序链表中重复的元素-II

目录 题目&#xff1a;删除有序链表中重复的元素-I_牛客题霸_牛客网 (nowcoder.com) 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 题目&#xff1a;删除有序链表中重复的元素-II_牛客题霸_牛客网 (nowcoder…

摩尔信使MThings实用功能盘点

“冗长的用户手册”与“精简的交互设计”之间势必产生一条信息鸿沟&#xff0c;现在就来盘点一下摩尔信使MThings有哪些隐蔽而实用的功能。 01 数据配置类 一键刷新 功能&#xff1a;快速读取所有位数据、寄存器数据的当前数值。 操作&#xff1a;双击“数值”列表头。 一键…

11:STM32---spl通信

目录 一:SPL通信 1:简历 2:硬件电路 3:移动数据图 4:SPI时序基本单元 A : 开/ 终条件 B:SPI时序基本单元 A:模式0 B:模式1 C:模式2 D:模式3 C:SPl时序 A:发送指令 B: 指定地址写 C:指定地址读 二: W25Q64 1:简历 2: 硬件电路 3:W25Q64框图 4: Flash操作注意…

MongoDB的搭建 和crud操作

MongoDB docker 下载 docker run --restartalways -d --name mongo -v /docker/mongodb/data:/data/db -p 27017:27017 mongo:4.0.6使用navcat工具使用MongoDB Crud操作 jar包 <dependency><groupId>org.projectlombok</groupId><artifactId>lom…

小小购物车案例(V3)

效果如下&#xff1a; 可以添加和减少商品个数&#xff08;最少个为1&#xff09;&#xff0c;在添加的时候总价格会随着改变&#xff0c;也可以点击按钮移除商品 代码分为三个模块&#xff08;html、js、css&#xff09; html部分&#xff1a; <!DOCTYPE html> <h…

计算机毕业设计 基于SSM+Vue的物资存储系统(以消防物资为例)的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

2023华为杯研究生数学建模竞赛选题统计+分析

2023年研赛的选题统计&#xff0c;我们主要基于根据两个平台投票统计。最终得出2023年研赛选题人数&#xff0c;这个结果仅供参考&#xff0c;但是应该具备一定的可信度。&#xff08;时间截止为22号中午1点&#xff09; 大家可以看到&#xff0c;AB题仅占10%&#xff0c;E题独…

操作系统:系统调用

1.系统调用的定义 凡是与共享资源有关的操作、会直接影响到其他进程的操作, 就一定需要操作系统介入,就需要通过系统调用来实现。 1.回顾系统调用 操作系统作为用户和计算机硬件之间的接口&#xff0c;需要向上提供一些简单易用的服务。主要包括命令接口和程序接口。其中&a…

Lua学习笔记:探究package

前言 本篇在讲什么 理解Lua的package 本篇需要什么 对Lua语法有简单认知 对C语法有简单认知 依赖Visual Studio工具 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#xff0c;快速上手 提供全流程的源码内容 ★提高阅读体验★ &#x1f449; ♠ 一级…

kafka的 ack 应答机制

目录 一 ack 应答机制 二 ISR 集合 一 ack 应答机制 kafka 为用户提供了三种应答级别&#xff1a; all&#xff0c;leader&#xff0c;0 acks &#xff1a;0 这一操作提供了一个最低的延迟&#xff0c;partition的leader接收到消息还没有写入磁盘就已经返回ack&#x…

Unity新收费模式:开启游戏开发者的持续盈利时代

Unity引擎近日宣布自2024年1月1日起&#xff0c;将根据游戏安装量对开发者进行收费。这一消息在游戏开发圈引起了广泛关注和讨论。根据Unity技术博客发布的《Unity收费模式和配套服务更新》一文&#xff0c;他们之所以选择这种计费方式&#xff0c;是因为每次游戏被下载时&…

基于SSM+Vue的亿互游在线平台的设计与开发

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Linux下的Docker安装,以Ubuntu为例

Docker是一种流行的容器化平台&#xff0c;它能够简化应用程序的部署和管理。 Docker安装 1、检查卸载老版本Docker&#xff08;为保证安装正确&#xff0c;尽量在安装前先进行一次卸载&#xff09; apt-get remove docker docker-engine docker.io containerd runc 2、Dock…

Qt创建线程(线程池)

1.线程池可以创建线程统一的管理线程&#xff08;统一创建、释放线程&#xff09; 2.使用线程池方法实现点击开始按钮生成10000个随机数&#xff0c;然后分别使用冒泡排序和快速排序排序这10000个随机数&#xff0c;最后在窗口显示排序后的数字&#xff1a; mainwindow.h文件…

基础课-排列组合

1.排列 2.组合 定义 从n个不同元素中&#xff0c;任意取出m(m<n)元素并为一组&#xff0c;叫做从n个不同元素中取出m个元素的一个组合 注意:1.不同元素 2.只取不排 3.相同组合:元素相同 3.把位置当成特殊元素 这个元素不一定入选的时候&#xff0c;把位置当特殊元素 4.插空…