使用签名检测 PDF 更改

2023-12-22

我正在开发一个 Web 应用程序,允许用户下载 PDF 文件,他们必须使用其证书使用 Adob​​e Acrobat 对该文件进行签名,然后上传回网络。

我在用着C# and itextsharp 5.5.9.0用于所有与 PDF 相关的工作。

现在,我需要检查该文档从网上下载后是否未被更改。我试图通过在让用户下载 PDF 文件之前添加我自己的签名来做到这一点(签名的实现或多或少类似于这个问题 https://stackoverflow.com/questions/26114019)。签名和验证工作正常,直到第二次对文件进行签名(使用用户的证书)。

之后第一个签名不知何故变得无效,我检查了两者itextsharp's AcroFields.SignatureCoversWholeDocument方法(它返回false)和 Adob​​e Acrobat UI 中(截屏 https://i.snag.gy/03SQIt.jpg).

所以,我有两个问题:

  1. 是否有可能检查文档在两次签名之间是否被修改?
  2. 如果不是 - 以编程方式的替代方法是什么(使用itextsharp)检查PDF文件在生成之后和签名之前是否被更改?

签名和验证工作正常,直到第二次对文件进行签名(使用用户的证书)。之后第一个签名不知何故变得无效

正如评论中已经澄清的那样,如果希望第一个签名保持有效,则必须以附加模式(iText 术语)/作为增量更新(PDF 规范术语)应用第二个签名。否则,签名字节很可能会发生变化,并且签名哈希值不再匹配。

  1. 是否有可能检查文档在两次签名之间是否被修改?

更准确地说,您的问题应该是是否可以检查两个签名之间的文档修改是否超出了嵌入第二个签名的合理更改。

简而言之:在您的用例中这是可能的,但仍然意味着相当多的工作和与 iText 低级 API 的杂耍。详细地:

一般来说,这并不是一件小事,因为添加具有可视化的新签名似乎是合理的

  • 更改相关页面的注释,因为签名可视化是小部件注释;
  • 更改 PDF 表单定义,因为签名锚定为表单字段;
  • 可以为其他表单字段创建外观流,以修复它们在签名文件中的确切外观;
  • 可以更改元数据流以记录签名行为;
  • 可能会更改文档的数字安全存储;
  • 可能会改变更多。

因此,检查更改是否属于这些类别中的任何一个并非易事。

此外,您还必须检查其他作弊行为,例如签名可视化可能会覆盖整个页面并显示该内容的操纵版本......

但你说你的用户

必须使用 Adob​​e Acrobat 签名

这可能使您的任务有些可行:如果您使用 Adob​​e Acrobat 将示例签名添加到您之前首先签署的多个文档中,则可以分析 Adob​​e Acrobat 在签署文档时通常会更改哪些文档。

利用这些知识,您可以实现一个类来检查是否仅存在这些更改。

  1. 如果不是 - 以编程方式(使用 itextsharp)检查 PDF 文件在生成之后和签名之前是否已更改的替代方法是什么?

如果没有您应用的第一个签名,情况就会变得更加困难,因为用户的 PDF 签名软件没有理由限制文档中的内部结构更改,只要它们不影响其外部行为。所以我会尝试使用双重签名。

或者,您可以尝试将原始文档和用户签名的版本呈现为位图并进行比较。仅应在放置用户签名可视化的区域中存在差异。这不会验证交互式 PDF 功能,但至少会验证打印输出的完整性。

渲染还不是 iText 的一个功能,但解析框架同时已经发展到足以充当渲染功能的基础。


应用第一个签名甚至可以帮助防止意外更改:如果您为用户提供空签名字段并自己使用认证签名,则可以将“允许的更改”限制为仅填充该空签名字段,并且 Adob​​e Acrobat 通常除非另有明确说明,否则尊重此类限制。


有关集成 PDF 签名的背景,请查看这个答案 https://security.stackexchange.com/a/35131/16096关于信息安全堆栈交换。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用签名检测 PDF 更改 的相关文章

  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • 按成员序列化

    我已经实现了template
  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 使用 Bearer Token 访问 IdentityServer4 上受保护的 API

    我试图寻找此问题的解决方案 但尚未找到正确的搜索文本 我的问题是 如何配置我的 IdentityServer 以便它也可以接受 授权带有 BearerTokens 的 Api 请求 我已经配置并运行了 IdentityServer4 我还在
  • 控件的命名约定[重复]

    这个问题在这里已经有答案了 Microsoft 在其网站上提供了命名指南 here http msdn microsoft com en us library xzf533w0 VS 71 aspx 我还有 框架设计指南 一书 我找不到有关
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • 覆盖子类中的字段或属性

    我有一个抽象基类 我想声明一个字段或属性 该字段或属性在从该父类继承的每个类中具有不同的值 我想在基类中定义它 以便我可以在基类方法中引用它 例如覆盖 ToString 来表示 此对象的类型为 property field 我有三种方法可以
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • 测试用例执行完成后,无论是否通过,如何将测试用例结果保存在变量中?

    我正在使用 NUNIT 在 Visual Studio 中使用 Selenium WebDriver 测试用例的代码是 我想在执行测试用例后立即在变量中记录测试用例通过或失败的情况 我怎样才能实现这一点 NUnit 假设您使用 NUnit

随机推荐

  • moveRowAtIndexPath 不带删除按钮

    我需要帮助UITableview具体来说 void tableView UITableView tableView moveRowAtIndexPath NSIndexPath sourceIndexPath toIndexPath NSI
  • 如何使用 Apache POI 创建 Word 文档?

    如何使用 Apache POI 创建 Word 文档 我正在为 Atlassian Confluence 开发一个简历编辑器作为商业插件 很抱歉我不得不问这个问题 但我找不到可以帮助我的教程 您附加的代码文件 DownloadAsMicro
  • Oracle会话临时表中的数据什么时候会被删除?

    我读到 在会话表中 数据在提交过程中仍然存在 用的话来说Ask Tom http asktom oracle com pls asktom f p 100 11 0 3a 3a 3a 3aP11 QUESTION ID 4881234805
  • 使用自定义 TextWriter 时 OutputStream 不可用

    这是我将 pdf 转换为 png 图像的函数 它抛出错误 这一行 gt stream WriteTo Response OutputStream 有什么不对 protected void CreatePngFromPdf try strin
  • Airflow:并行链接任务

    我目前正在开发一个 DAG 需要每月循环处理一长串任务 为了实现这一点 我创建一个空列表 然后循环多个任务 根据新的月份更改它们的 task id Example from airflow import DAG from airflow o
  • Crashlytics 的 Beta 版无法在测试人员的设备上安装构建版本

    我将我的应用程序发送给测试人员来自 Crashlytics 的测试版 http try crashlytics com beta 这是一个很棒的应用程序测试工具 我在我的开发者帐户中注册了每个新测试人员的设备 UDID 然后分发新版本 我的
  • iOS 11 大标题导航栏不折叠

    苹果公司的家伙Cocoa Touch WWDC 视频中有哪些新内容 https developer apple com videos play wwdc2017 201 新的大标题导航栏将神奇地挂钩到底层视图控制器的顶级滚动视图 并在上下滚
  • Python 使用 xarray 从 NETCDF 文件中提取多个纬度/经度

    我有一个 NC 文件 时间 纬度 经度 从这里下载 https filebin net e3f1n1tl82dosq1w example nc t z86058ad我正在尝试提取多个站点的时间序列 纬度 经度点从这里下载 https fil
  • 为什么我的表没有显示在 SQL Server Management Studio 智能感知中?

    我无法调出表以便在存储过程中使用它们 他们没有出现的原因是什么 您刚刚创建它们吗 它使用的智能感知数据被缓存 尝试刷新一下 编辑 gt IntelliSense gt 刷新本地 缓存
  • 在 Access 2013 中使用 VBA 打开 Word 文档

    我正在使用 Access 2013 并在表单上创建了一个帮助按钮 我想打开带有说明的 Word 文档 这是我尝试过的代码 Private Sub cmdHelp Click Dim wrdApp As Word Application Di
  • 如何在单元格中显示进度?

    我使用代码didSelectRowAt indexPath 要开始在单元格上下载文件 请单击 我使用代码cellForRowAt indexPath 显示现在下载文件的进度 class TableViewController UITable
  • 过渡在 IE 中不起作用

    我正在开发自己的网站 它的 功能 之一是当我将鼠标悬停在标题上时 它会向下滑动 这在所有主流浏览器上都运行良好 但是 对于 IE 10 情况并非如此 这是页面来源 这是包含的头文件
  • C 函数参数中的 __cdecl 有什么用

    我正在学习C语言 在学习的过程中我发现了一行对我来说全新且陌生的代码void PullDown char int void cdecl void 我只知道第一个和第二个参数 我想知道第三个参数 cdecl 之后的两个星号有什么用 我从这个语
  • 通过 WordPress 简码将自定义文本添加到联系表单 7

    我正在使用联系表单 7 需要在表单的某处添加自定义文本 我从高级自定义字段的子字段中使用 PHP 获取自定义文本 我知道 有一个名为 Contact Form 7 Dynamic Text Extension 的额外插件 https de
  • 使用 FileReader 的 readAsBinaryString 和 readAsText 之间的区别

    举个例子 当我读到 字符时 u03C0 从使用 FileReader API 的文件中 当我使用以下命令读取它时 我会得到 pi 字符FileReader readAsText blob 这是预期的 但是当我使用FileReader rea
  • 在 JavaScript 中将 RSS pubDate 解析为 Date 对象

    我该怎么做 2010 年 2 月 2 日星期二 19 34 21 等 GMT 它开箱即用 JavaScript 中的 Date 对象可以通过传递一些标准时间格式来设置 RSS 中使用的格式就是其中之一 Example var pubDate
  • Java 函数的递归版本在第一次调用时比迭代慢,但之后更快。为什么是这样?

    对于一项作业 我目前正在尝试测量矩阵链问题的迭代解决方案与递归解决方案之间的性能 空间 时间 差异 问题的要点和我用于迭代版本的解决方案可以在这里找到 http www geeksforgeeks org dynamic programmi
  • R 日期时间序列缺失值

    我正在从 chr 转换为格式为 Y m d H M S 的 POSIXct 但是 数据集中的某些时间没有秒部分 S 因此当我转换为DateTime 不带秒的时间将作为空单元格返回 NA我如何确保这种情况不会发生 我希望它们全部作为 Date
  • 使用实体框架 Code First 进行事务处理

    有一个答案here https stackoverflow com questions 815586 entity framework using transactions or savechangesfalse and acceptall
  • 使用签名检测 PDF 更改

    我正在开发一个 Web 应用程序 允许用户下载 PDF 文件 他们必须使用其证书使用 Adob e Acrobat 对该文件进行签名 然后上传回网络 我在用着C and itextsharp 5 5 9 0用于所有与 PDF 相关的工作 现