使用摘要异步签署 pdf

2023-12-29

我正在尝试执行以下设置来签名 pdf,分为客户端和服务器之间的异步步骤:

  1. 服务器接收 pdf 并计算其摘要。
  2. 服务器将摘要发送给客户端。
  3. 客户端稍后签署哈希值。
  4. 客户端将签名发送给服务器。
  5. 服务器将签名嵌入到 pdf 中。

我主要立足于PDF 签名摘要 https://stackoverflow.com/questions/29251895/pdf-signature-digest and 从文件摘要创建 pkcs7 签名 https://stackoverflow.com/questions/41767351/create-pkcs7-signature-from-file-digest

第二个问题允许我编写大部分代码,但是我发现文件的完整性已受到损害。我似乎无法序列化中间 pdf 以稍后嵌入签名(以确保没有时间戳被更改等)。但从第一个问题来看,这似乎是一个比我想象的更难的问题。真的可以做到吗?

我正在使用 pdfbox。

服务器代码:

        PDDocument document = PDDocument.load(documentFile);
        PDSignature signature = new PDSignature();
        signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
        signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
        signature.setName("Example User");
        signature.setLocation("Los Angeles, CA");
        signature.setReason("Testing");
        Calendar date = Calendar.getInstance();
        signature.setSignDate(date);
        document.addSignature(signature);

        ExternalSigningSupport externalSigningSupport = document.saveIncrementalForExternalSigning(null);

        byte[] content = IOUtils.toByteArray(externalSigningSupport.getContent());
        MessageDigest md = MessageDigest.getInstance("SHA256", new BouncyCastleProvider());
        byte[] digest = md.digest(content); // this is sent to client

我基本上所做的是将摘要发送给客户端进行签名,然后在服务器上重做上述步骤并设置客户端签名:

        ExternalSigningSupport externalSigning = document.saveIncrementalForExternalSigning(fos);
        externalSigning.setSignature(encodedSignature); // encodedSignature is received from client and computed based on the digest sent by the server

此设置最终导致文件的完整性被破坏,因为一旦我拥有了,我就会创建一个新的 PDSignatureencodedSignature在服务器上嵌入它。有没有办法序列化调用 addSignature 后创建的 PDDocument,以便我稍后可以在服务器上反序列化它并添加客户端的签名?


我基本上所做的是将摘要发送给客户端进行签名,然后在服务器上重做上述步骤并设置客户端签名

如果你想要那些以上步骤要生成相同的文档,您需要

  • 确保这些步骤的输入相同并且
  • 提供相同的修订 ID 种子值。

如果这样做,则输出以上步骤与您的任务所需的相同。

确保输入相同

你的一步以上步骤很容易导致不同的输入:

Calendar date = Calendar.getInstance();
signature.setSignDate(date);

为了保证相同的输入,您必须确定date仅一次,并且每次为同一签名交易执行这些步骤时都使用该单个值。

提供相同的修订 ID 种子值

根据规范的建议,PDFBox 尝试为每个 PDF 修订版提供唯一的 ID。不过,在当前的情况下,我们两次都需要相同的修订 ID以上步骤被处决。

幸运的是,PDFBox 允许我们提供它用来使修订 ID 足够唯一的种子值。

由于我们不希望在同一文档上始终使用相同的修订 ID,而只是在当前签名交易期间使用相同的修订 ID,因此我们应该仅在同一交易中使用相同的种子值。由于种子值很长,我们可以简单地使用对应于种子值的时间(以毫秒为单位)date上面已经讨论过,即:

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

使用摘要异步签署 pdf 的相关文章

随机推荐

  • Mongodb - 可靠性问题仍然很重要吗?

    我有几个 sqlite 数据库 我想说大约 15GB 总共大约 100 万行 所以不是很大 我正在研究 mongodb 它看起来很容易使用 特别是如果我想尝试对构成数据库的文档进行一些基本的自然语言处理 我过去从未使用过 Mongo 不需要
  • Pandas:计算列中日期时间对象的频率

    我有一列 来自原始数据 我已将其从字符串转换为 Pandas 中的日期时间对象 该列如下所示 0 2012 01 15 11 10 12 1 2012 01 15 11 15 01 2 2012 01 16 11 15 12 3 2012
  • 如何减小 Subversion 存储库的大小?

    我有一对 svn 存储库 它们比其他存储库大得多 它们对于 svn 来说并不算太大 但它们占用了大量磁盘空间 我宁愿将其用于其他用途 有哪些策略可用于减少 svn 存储库的磁盘使用 我尝试了 删除无效交易 部分此处描述 http svnbo
  • 什么是 Django South GhostMigrations 异常以及如何调试它?

    对我的 Django 应用程序的模型进行了一些更改 并使用 South 将它们迁移到我的开发计算机上 迁移 0004 到 0009 但是当尝试在服务器上迁移这些更改时 我收到 GhostMigrations 错误 没有太多好的内容来解释什么
  • 在 Xcode 6 iPhone 模拟器的 iOS 8 UITableView 上删除 SeparatorInset

    我发现了一个奇怪的空白UITableView for iPhone 6 模拟器 iOS 8 在 Xcode 6 GM 上 我尝试过设置SeparatorInset来自故事板和代码 但空白区域就在那里 以下代码适用于 iOS 7 但不适用于
  • Emacs 重命名变量

    如何在 emacs 中重命名变量 Eclipse 有一个简洁的 重命名 重构操作 它允许您以范围感知的方式重命名变量 这比本地化替换字符串更容易使用 特别是当变量名称是像 e 这样的字符时 emacs 是否内置了类似的功能 新的 Emacs
  • 如何实现 JDatePicker

    我正在使用 JDatePicker 的最新版本 1 3 4 应该如何实施 我收到编译器错误 构造函数 JDatePanelImpl UtilDateModel 未定义 建议的修复方法是 添加参数以匹配 JDatePanelImpl Date
  • 如何在WCF服务中将接口作为参数传递?

    我有以下内容 但我不确定这是正确的方法 namespace WCFServices ServiceContract Name IService ServiceKnownTypeAttribute typeof DataItem public
  • Pandas 中双括号 `[[...]]` 和单括号 `[..]` 索引之间的区别

    我对以下代码行的语法感到困惑 x values dataframe Brains 数据框对象由 2 列 Brains 和 Bodies 组成 Brains Bodies 42 34 32 23 当我打印 x values 时 我得到这样的信
  • 如何将数据存储到数据库(sqlite)

    在 iOS 上 我想使用 sqlite 将用户数据存储在数据库中 对于该设计 Xib 文件用户名 密码 出生日期作为文本字段并采用按钮 填写所有文本字段后 单击按钮时所有数据都存储在数据库中 我假设您已经了解 Outlet 的工作原理以及如
  • 如何将额外的属性字段添加到 asp.net 下拉列表中

    下面我可以设置值和文本 dropListUserImages DataValueField Value dropListUserImages DataTextField Text dropListUserImages Items Add n
  • JavaScript 匿名构造函数:!function(){}();

    我见过在 JavaScript 中创建匿名构造函数的语法 var Application Application function window Application Application property Application me
  • 在 Access 中对链接的 Excel 表执行 SQL 更新

    使用 Access 2010 我将多个 Excel 表导入到 Access 中 并构建了允许用户更新信息并向表添加信息的表单 这些表单的工作方式是在 VBA 中动态生成 SQL alter 和 update 语句 然后运行DoCmd Run
  • Python C API:如何使用 Py_eval_input 获取 PyRun_String 以使用导入的模块?

    PyRun String random randint 1 10 Py eval input globals globals 返回错误 Traceback most recent call last File
  • 当自动高度已设置时,Ext js 动态设置网格高度的问题

    当初始设置的自动高度为 true 时 我试图切换网格的高度 我希望能够在网格变得大于浏览器视图时切换高度 网格位于没有外部视口的普通页面上 如果我尝试设置这样的高度 那么我就会松开滚动条 我可以在 firebug 中看到溢出设置为可见而不是
  • 无法使用 std=c++11 设置 Eclipse Juno C++

    我有 Eclipse Juno C 构建 ID 20120614 1722 我尝试使用指令 std c 11 或 std c 0x 设置编译器调用参数 但在编译下面的代码时 Eclipse Juno 中没有 工具设置 至少对于 Mac 因此
  • 致命错误:Python.h:没有这样的文件或目录 - 未使用 python-devel 解决[重复]

    这个问题在这里已经有答案了 此问题与之前的问题类似 但无法使用相同的建议来解决 我正在使用 Centos 7 在运行 Python 3 5 最新稳定版本 的虚拟环境中 我尝试安装psycopg2通过使用 pip3 pip easy inst
  • 如何在OpenGL/GLUT中计算用鼠标移动相机的观察点?

    这对我来说解释起来会很混乱 所以请耐心等待 我已经在我的相机类中实现了大多数类型的移动和旋转 一切都可以通过键盘进行 现在我想实现鼠标 我像这样捕获鼠标移动 define SENSITIVITY 25 0f void main void g
  • 使用覆盖 new[] 运算符创建字符串数组

    我们和我的朋友一起制作了一个带有覆盖 new 和 new 运算符的程序 我发现当我尝试使用以下代码创建字符串数组时 string Test1 new string 10 函数返回无效指针 通常它的值向前移动 8 位 我正在将程序编译到 x6
  • 使用摘要异步签署 pdf

    我正在尝试执行以下设置来签名 pdf 分为客户端和服务器之间的异步步骤 服务器接收 pdf 并计算其摘要 服务器将摘要发送给客户端 客户端稍后签署哈希值 客户端将签名发送给服务器 服务器将签名嵌入到 pdf 中 我主要立足于PDF 签名摘要