当前位置: 首页 > news >正文

C# 验证PDF数字签名的有效性

数字签名作为PDF文档中的重要安全机制,不仅能够验证文件的来源,还能确保文件内容在传输过程中未被篡改。然而,如何正确验证PDF文件的数字签名,是确保文件完整性和可信度的关键。本文将详细介绍如何使用免费.NET控件通过C#验证PDF签名的有效性以及验证PDF文档是否被修改

免费.NET PDF库安装:

Free Spire.PDF for .NET 免费库可以通过NuGet直接安装,或者通过以下链接下载产品包解压缩后手动引用dll。

https://www.e-iceblue.com/Download/download-pdf-for-net-free.html

使用C# 验证PDF数字签名有效性

Free Spire.PDF 提供了 PdfSignature 类用于代表PDF文档中的数字签名,要验证签名的有效性可以用该类的 VerifySignature() 方法。

主要步骤:

  1. 创建PdfDocument 对象,并使用 LoadFromFile() 方法加载 PDF 文件。
  2. 获取 PDF 文件中的表单,然后使用获取表单字段集合。
  3. 遍历所有字段,并判断当前字段是否为签名字段(PdfSignatureFieldWidget 类)。
  4. 如果是签名字段,则通过 PdfSignatureFieldWidget.Signature 属性获取该PDF 签名。
  5. 使用 PdfSignature.VerifySignature() 方法检查 PDF 签名的有效性
  6. 输出结果。

C#示例代码:

using Spire.Pdf;
using Spire.Pdf.Security;
using Spire.Pdf.Widget;namespace VerifySignature
{class Program{static void Main(string[] args){//加载PDF文档PdfDocument pdf = new PdfDocument();pdf.LoadFromFile("PDF签名.pdf");//获取PDF文件中的表单字段集合PdfFormWidget pdfFormWidget = (PdfFormWidget)pdf.Form;PdfFormFieldWidgetCollection pdfFormFieldWidgetCollection = pdfFormWidget.FieldsWidget;//遍历所有字段for (int i = 0; i < pdfFormFieldWidgetCollection.Count; i++){//获取签名字段if (pdfFormFieldWidgetCollection[i] is PdfSignatureFieldWidget){PdfSignatureFieldWidget signatureFieldWidget = (PdfSignatureFieldWidget)pdfFormFieldWidgetCollection[i];//获取PDF签名PdfSignature signature = signatureFieldWidget.Signature;//验证签名有效性bool valid = signature.VerifySignature();if (valid){Console.WriteLine("有效签名");}else{Console.WriteLine("无效签名");}}}}}
}

验证结果:
验证PDF签名

使用C# 验证PDF文档是否被修改

验证PDF文档是否被修改也能间接验证电子签名的有效性,如果在签名之后文档内容被修改,那么PDF签名也将失效。通过使用 PdfSignature 类提供的 VerifyDocModified() 方法可以快速验证PDF文档的完整性。

主要步骤:

  1. 创建 PdfDocument 对象,并使用 LoadFromFile() 方法加载 PDF 文件
  2. 获取 PDF 文件中的表单,然后使用获取表单字段集合。
  3. 遍历所有字段,并判断当前字段是否为签名字段(PdfSignatureFieldWidget 类)。
  4. 如果是签名字段,则通过 PdfSignatureFieldWidget.Signature 属性获取该PDF 签名。
  5. 使用 PdfSignature.VerifyDocModified() 方法验证签名后文档是否被修改。
  6. 输出结果。

C#示例代码:

using Spire.Pdf;
using Spire.Pdf.Security;
using Spire.Pdf.Widget;namespace CheckSignature
{class Program{static void Main(string[] args){//加载PDF文档PdfDocument pdf = new PdfDocument();pdf.LoadFromFile("PDF签名.pdf");//获取PDF文件中的表单字段集合PdfFormWidget pdfFormWidget = (PdfFormWidget)pdf.Form;PdfFormFieldWidgetCollection pdfFormFieldWidgetCollection = pdfFormWidget.FieldsWidget;//遍历所有字段for (int i = 0; i < pdfFormFieldWidgetCollection.Count; i++){//获取签名字段if (pdfFormFieldWidgetCollection[i] is PdfSignatureFieldWidget){PdfSignatureFieldWidget signatureFieldWidget = (PdfSignatureFieldWidget)pdfFormFieldWidgetCollection[i];//获取PDF签名PdfSignature signature = signatureFieldWidget.Signature;//验证签名后PDF文档是否被修改bool modified = signature.VerifyDocModified();if (modified){Console.WriteLine("文档被修改了。");}else{Console.WriteLine("文档未被修改。");}}}}}
}

验证结果:
验证PDF文档完整性

通过这些步骤和示例代码,我们可以确保PDF文档的完整性和电子签名的有效性,从而在处理重要文件时提供额外的安全保障。


相关文章推荐:
C# 在PDF中添加数字签名
C# 获取PDF数字签名证书
C# 加密、解密PDF文档

相关文章:

C# 验证PDF数字签名的有效性

数字签名作为PDF文档中的重要安全机制&#xff0c;不仅能够验证文件的来源&#xff0c;还能确保文件内容在传输过程中未被篡改。然而&#xff0c;如何正确验证PDF文件的数字签名&#xff0c;是确保文件完整性和可信度的关键。本文将详细介绍如何使用免费.NET控件通过C#验证PDF签…...

2小时动手学习扩散模型(pytorch版)【入门版】【代码讲解】

2小时动手学习扩散模型&#xff08;pytorch版&#xff09; 课程地址 2小时动手学习扩散模型&#xff08;pytorch版&#xff09; 课程目标 给零基础同学快速了解扩散模型的核心模块&#xff0c;有个整体框架的理解。知道扩散模型的改进和设计的核心模块。 课程特色&#xf…...

Centos7网络配置(设置固定ip)

文章目录 1进入虚拟机设置选中【网络适配器】选择【NAT模式】2 进入windows【控制面板\网络和 Internet\网络和共享中心\更改适配器设置】设置网络状态。3 设置VM的【虚拟网络编辑器】4 设置系统网卡5 设置虚拟机固定IP 刚安装完系统&#xff0c;有的人尤其没有勾选自动网络配置…...

英伟达被“压制”的25年

十九世纪中叶的美国西部&#xff0c;掀起了一场轰轰烈烈的淘金热&#xff0c;但最终赚到钱的&#xff0c;并不是拿命去赌的淘金者。一个名叫萨姆布瑞南的商人&#xff0c;通过向淘金者出售铲子&#xff0c;成了加州历史上第一位百万富翁。 每一次风口出现时&#xff0c;总有企…...

windows安装Gitblit还是Bonobo Git Server

Gitblit 和 Bonobo Git Server 都是用于托管Git仓库的工具&#xff0c;但它们是基于不同平台的不同软件。 Gitblit 是一个纯 Java 写的服务器&#xff0c;支持托管 Git&#xff0c;Mercurial 和 SVN 仓库。它需要 Java 运行环境&#xff0c;适合在 Windows、Linux 和 Mac 平台…...

仪器校准的概念与定义,计量校准是什么?

仪器校准的定义&#xff0c;在之前所颁布的《国际计量学词汇 基础和通用概念及相关术语》文件中&#xff0c;已经有了明确说明&#xff0c;而该文件做了修改以后&#xff0c;在后续新的定义中&#xff0c;仪器校准具体被分为两部分&#xff0c;第一步是将被计量仪器和计量校准的…...

Vue3+Pinia

1.单纯调接口(安装pinia及引入如下第一张图) 1.npm install pinia2.在main.js里引入即可import { createPinia } from piniaapp.use(createPinia()) 1.stores建立你文件的ts、内容如下&#xff1a;1-1 import { defineStore } from pinia1-2 import { findPageJobSet } from …...

label studio数据标注平台的自动化标注使用

&#xff08;作者&#xff1a;陈玓玏&#xff09; 开源项目&#xff0c;欢迎star哦&#xff0c;https://github.com/data-infra/cube-studio 做图文音项目过程中&#xff0c;我们通常会需要进行数据标注。label studio是一个比较好上手的标注平台&#xff0c;可以直接搜索…...

高并发场景下的热点key问题探析与应对策略

目录 一、问题描述 二、发现机制 三、解决策略分析 &#xff08;一&#xff09;解决策略一&#xff1a;多级缓存策略 客户端本地缓存 代理节点本地缓存 &#xff08;二&#xff09;解决策略二&#xff1a;多副本策略 &#xff08;三&#xff09;解决策略三&#xff1a;热点…...

学习一下C++中的枚举的定义

目录 普通枚举 强类型枚举 普通枚举 枚举类型在C中是通过关键字enum来定义的。下面是一个简单的例子&#xff1a; enum Color { RED, GREEN, BLUE }; 在这个例子中&#xff0c;我们定义了一个名为Color的枚举类型&#xff0c;它包含了三个枚举值&#xff1a;RED、GRE…...

开发一套java语言的智能导诊需要什么技术?java+ springboot+ mysql+ IDEA互联网智能3D导诊系统源码

开发一套java语言的智能导诊需要什么技术&#xff1f;java springboot mysql IDEA互联网智能3D导诊系统源码 医院导诊系统是一种基于互联网和3D人体的智能化服务系统&#xff0c;旨在为患者提供精准、便捷的医院就诊咨询服务。该系统整合了医院的各种医疗服务资&#xff1b;智慧…...

C++| STL之string

前言&#xff1a;最近在做LeetCode算法题&#xff0c;C字符串通常都是string作为输入&#xff0c;所以补充一下STL里面string。在介绍的具体使用的时候&#xff0c;会补充char字符串相关的进行对比。 string 创建大小和容量遍历字符串比较插入字符拼接字符串分配内存查找截取分…...

[数据集][目标检测]游泳者溺水检测数据集VOC+YOLO格式4599张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4599 标注数量(xml文件个数)&#xff1a;4599 标注数量(txt文件个数)&#xff1a;4599 标注…...

JAVA实现麦克风说话同声传译

一、能力与场景说明 同声传译&#xff0c;又称同步口译或同声翻译&#xff0c;是一种专业的口译形式&#xff0c;指的是在讲话者发言时&#xff0c;口译员几乎同时将讲话内容翻译成目标语言。这种翻译方式通常用于国际会议、高级别政治或商业会谈、研讨会和其他需要即时多语言…...

LabVIEW与PLC通讯方式及比较

LabVIEW与PLC之间的通讯方式多样&#xff0c;包括使用MODBUS协议、OPC&#xff08;OLE for Process Control&#xff09;、Ethernet/IP以及串口通讯等。这些通讯方式各有特点&#xff0c;选择合适的通讯方式可以提高系统的效率和稳定性。以下将详细介绍每种通讯方式的特点、优点…...

2024/6/30 英语每日一段

Years of economic and political turbulence have brought stagnation.“In a world where there is more risk and uncertainty, people become reluctant to voluntarily move jobs and find better jobs,” says Manning. At the same time, businesses have cut back on i…...

Postman接口测试工具的原理及应用详解(五)

本系列文章简介&#xff1a; 在当今软件开发的世界中&#xff0c;接口测试作为保证软件质量的重要一环&#xff0c;其重要性不言而喻。随着前后端分离开发模式的普及&#xff0c;接口测试已成为连接前后端开发的桥梁&#xff0c;确保前后端之间的数据交互准确无误。在这样的背景…...

208.贪心算法:买卖股票的最佳时机||(力扣)

代码解决 class Solution { public:int maxProfit(vector<int>& prices) {int result 0; // 初始化结果为0&#xff0c;表示初始利润为0// 从第二天开始遍历价格数组for (int i 1; i < prices.size(); i) {// 如果当天价格比前一天价格高&#xff0c;则将差价加…...

【论文阅读】伸缩密度比估计:Telescoping Density-Ratio Estimation

文章目录 一、文章概览&#xff08;一&#xff09;问题提出&#xff08;二&#xff09;文章工作 二、判别比估计和密度鸿沟问题三、伸缩密度比估计&#xff08;一&#xff09;核心思想&#xff08;二&#xff09;路标创建&#xff08;三&#xff09;桥梁构建&#xff08;四&…...

MongoDB数据库 MQL (MongoDB Query Language)语句大全

基本命令 连接到 MongoDB mongo显示所有数据库 show dbs选择&#xff08;或创建&#xff09;数据库 db集合操作 显示当前数据库中的所有集合 show collections创建集合 db.createCollection("myCollection")删除集合 db.myCollection.drop()文档操作 插入文…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...