签名字段中的“锁定”字典是签名后签名损坏的原因

2024-03-05

在 PDFBox 2.x 中我把/Lock字典到签名字段:

import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;

public class SigningUtils {
    public static final COSName COS_NAME_LOCK = COSName.getPDFName("Lock");
    public static final COSName COS_NAME_ACTION = COSName.getPDFName("Action");
    public static final COSName COS_NAME_ALL = COSName.getPDFName("All");
    public static final COSName COS_NAME_SIG_FIELD_LOCK = COSName.getPDFName("SigFieldLock");

    public static void setLock(PDSignatureField pdSignatureField, PDAcroForm acroForm) {
        COSDictionary lockDict = new COSDictionary();
        lockDict.setItem(COS_NAME_ACTION, COS_NAME_ALL);
        lockDict.setItem(COSName.TYPE, COS_NAME_SIG_FIELD_LOCK);
        pdSignatureField.getCOSObject().setItem(COS_NAME_LOCK, lockDict);
    }
}

然后我在签名字段上签名:

PDSignature signature = findExistingSignature(document, signatureFieldName); //This is some method to find signature field and create PDSignature dictionary

signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);

signature.setName("blablabla");
signature.setLocation("blablabla");
signature.setReason("blablabla");
signature.setSignDate(Calendar.getInstance());
document.addSignature(signature, this);

一切看起来都不错,除了当我在 Adob​​e Acrobat 中打开签名文档时,它抱怨文档内容已更改。如果我不添加/Lock字典里一切都很好。

任何人都知道出了什么问题吗?


问题是 PDFBox 签名不接受Lock字典考虑在内。

根据 ISO 32000-1(以及类似的 ISO 32000-2):

12.8.2.4 现场MDP

The FieldMDP变换方法应用于检测表单字段列表值的更改。表 256 列出了其变换参数字典中的条目。

[...]

  • 作者还可以指定在特定收件人签署文档后,对特定表单字段的任何修改都将使该收件人的签名无效。每个指定的接收者都应有一个单独的签名字段,每个签名字段都有一个关联的签名字段锁定字典(见表 233),指定应为该用户锁定的表单字段。

  • 当接收者对该字段进行签名时,应创建签名、签名引用和转换参数字典。这Action and Fields转换参数字典中的条目应从签名字段锁定字典中的相应字段复制。

因此,签名的预期处理Lock字典包括添加匹配FieldMDP将数据转换为签名字段值。默认情况下,PDFBox 签名不会执行此操作。

您可以在签名时手动执行以下操作:

PDSignatureField signatureField = FIND_YOUR_SIGNATURE_FIELD_TO_SIGN;
PDSignature signature = new PDSignature();
signatureField.setValue(signature);

COSBase lock = signatureField.getCOSObject().getDictionaryObject(COSName.getPDFName("Lock"));
if (lock instanceof COSDictionary)
{
    COSDictionary lockDict = (COSDictionary) lock;
    COSDictionary transformParams = new COSDictionary(lockDict);
    transformParams.setItem(COSName.TYPE, COSName.getPDFName("TransformParams"));
    transformParams.setItem(COSName.V, COSName.getPDFName("1.2"));
    transformParams.setDirect(true);
    COSDictionary sigRef = new COSDictionary();
    sigRef.setItem(COSName.TYPE, COSName.getPDFName("SigRef"));
    sigRef.setItem(COSName.getPDFName("TransformParams"), transformParams);
    sigRef.setItem(COSName.getPDFName("TransformMethod"), COSName.getPDFName("FieldMDP"));
    sigRef.setItem(COSName.getPDFName("Data"), document.getDocumentCatalog());
    sigRef.setDirect(true);
    COSArray referenceArray = new COSArray();
    referenceArray.add(sigRef);
    signature.getCOSObject().setItem(COSName.getPDFName("Reference"), referenceArray);
}

signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
signature.setName("blablabla");
signature.setLocation("blablabla");
signature.setReason("blablabla");
signature.setSignDate(Calendar.getInstance());
document.addSignature(signature [, ...]);

(创建签名 https://github.com/mkl-public/testarea-pdfbox2/blob/master/src/test/java/mkl/testarea/pdfbox2/sign/CreateSignature.java#L328辅助方法signExistingFieldWithLock)


关于P签名中的条目Lock评论中讨论的字典:此条目已在 ISO 32000 扩展级别 3 的 Adob​​e 补充中引入。

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

签名字段中的“锁定”字典是签名后签名损坏的原因 的相关文章

  • 匿名内部类显示不正确的修饰符

    据我了解 以下代码应该打印true作为输出 但是 当我运行这段代码时 它正在打印false 来自 Java 文档15 9 5 匿名类 https docs oracle com javase specs jls se8 html jls 1
  • 如何用Java创建图像

    比如说在我的程序中 我有这个paint 方法 我的愿望是创建所绘制的矩形的图像 使用 for 循环 我尝试了下面的方法 它确实给了我那些矩形 蓝色 但背景是全黑的 当我运行程序而不创建图像 仅在 JFrame 上绘制矩形时 背景为白色 我怎
  • java.sql.SQLException: ORA-01005: 给定的密码为空;登录被拒绝

    我在尝试连接到数据库时遇到以下异常 java sql SQLException ORA 01005 null password given logon denied at oracle jdbc driver T4CTTIoer proce
  • 无法解析配置“:app:debugRuntimeClasspath”的所有文件。问题

    我的 android studio 遇到了下一个问题 导致 org gradle api internal artifacts ivyservice DefaultLenientConfiguration ArtifactResolveEx
  • 在 JSP 中对表单操作使用相对路径

    如何在表单操作中使用相对路径
  • Java 将字节转换为二进制安全字符串

    我有一些以字节为单位的数据 我想将它们放入Redis中 但是Redis只接受二进制安全字符串 而我的数据有一些二进制非安全字节 那么如何将这些字节转换为二进制安全字符串以便将它们保存到 Redis 中呢 Base64 对我有用 但它使数据更
  • 将 emoji 替换为适当的 java 代码

    我正在开发一个简单的java程序 它可以接受这样的字符串 停止 你违反了 法律 但是现在 你 并将每个表情符号替换为适当的 java 字符 我不知道该怎么称呼他们 这是一个例子 汽车表情符号 将替换为 uD83D uDE97 这允许我有一个
  • Keycloak 社交登录 REST API

    我已经为我的 keycloak 实例启用了谷歌社交登录 但我需要将其用作休息服务 是否有可用于执行此操作的端点 Keycloak 中没有 Google 身份验证 API 但您可以使用以下方法解决它代币交换 https www keycloa
  • Java 中意外的负数

    import java util public class Prac9FibonacciNumbers public static void main String args int x new int 100 x 0 1 x 1 1 fo
  • 将传入字符串的 unicode 表示形式转换为 UTF-8?

    我正在读取一些已经转换为 html 样式 代码的数据 我现在需要将其转换回 UTF 8 字符以供查看 不幸的是我无法使用浏览器查看该字符串 我读过有关 java 中的转换的内容 似乎如果你有一个 uxxxx 字符串 那么编译器会为你转换 然
  • 如何减少 JSF 中的 javax.faces.ViewState

    减少 JSF 中视图状态隐藏字段大小的最佳方法是什么 我注意到我的视图状态约为 40k 这会在每次请求和响应时下降到客户端并返回到服务器 特别是到达服务器时 这对用户来说会显着减慢 我的环境 JSF 1 2 MyFaces Tomcat T
  • JSP 作为电子邮件模板

    有没有办法发送 MIME 电子邮件 其中电子邮件正文源自 JSP 我需要使用 Javamail 发送一封电子邮件 其中包含一个表格 我认为如果我可以使用 JSP 来完成所有格式设置和布局 将会很方便 在这个线程中 Java 电子邮件模板的建
  • 日志记录在 Android 设备上实际上有什么作用?

    我一直在 Android 示例中看到这样的代码 try catch Exception e Log e Error e getMessage 什么是Log e实际上在物理设备上做什么 它进入系统日志 开发人员可以通过 SDK 工具访问该日志
  • EclipseLink 2.7.0 和 JPA API 2.2.0 - 签名不匹配

    当运行由maven构建的具有以下依赖项的项目时
  • Android - 保持用户登录状态

    我正在尝试使用 PHP 和 MySQLi for Android 进行登录 我不明白的是如何保持用户登录状态 我看到一个简单的教程 其中有人使用 SQLite 来保护信息 但我不知道这是否真的安全 如何保存用户信息以保持用户登录状态 谢谢
  • HashSet 与 LinkedHashSet

    它们之间有什么区别 我知道 LinkedHashSet 是 HashSet 的有序版本 维护一个跨所有元素的双向链接列表 使用此类代替 HashSet 当您关心迭代顺序时 当你迭代 HashSet 时 顺序是不可预测的 而 LinkedHa
  • 线程睡眠阻止我的 Swing 应用程序执行

    我的应用程序发生的事情是有道理的 但我不知道如何修复它 以下是我的应用程序功能的简要描述 计时器窗口应显示在屏幕右下角并显示实时时间 一小时后 它应该执行一些操作 我还没有决定该操作 我面临的问题是定时器 java当我刷新实时计时器的秒数时
  • 有时 Properties.load() 会跳过行

    在以下情况下 Properties load 会跳过 InputStream 的第二行 这是 Java 的错误还是正常行为 public class PropTest public static void main String args
  • 根据 Java 环境变量中的值创建使用 @JsonIgnore 的自定义注释

    我需要创建一个新的注释 用于在环境变量设置时忽略输出 JSON 文件中的字段var false 我尝试使用JsonAnnotationIntrospector 但无法获得预期的输出 public class Vehicle String v
  • 对 Java 协议缓冲区对象进行一些小更改

    我想在 Java 协议缓冲区对象树的深处进行一个小更改 我可以使用 getBuilder 方法来创建一个新对象 该新对象是旧对象的克隆并进行一些更改 当深入完成此操作时 代码会变得丑陋 Quux Builder quuxBuilder fo

随机推荐

  • 嵌入 python 错误 不支持按文件名导入

    我正在尝试将 python 嵌入到我的应用程序中 但很早就陷入了困境 我将 python 嵌入到我的 C 应用程序中并使用本教程中找到的代码 http docs python org 2 extending embedding html p
  • Android:使用 DrawableCompat 着色

    我正在尝试对 Android API 级别 21 之前的图像进行着色 我已经使用以下方法成功对项目进行了着色
  • XHR跨域限制的目的是什么?

    我一直想知道XHR跨域限制的目的是什么 其目的似乎是防止恶意注入的 Javascript 将私有数据发送给攻击者 然而 通过注入可以轻松地将数据发送到任何域script or img标签 或任何其他与此相关的外部资源 如果任意网站可以对您的
  • django Rest框架::传递原始查询

    是否可以在 django Rest 框架 如 django rest 中执行原始查询 https docs djangoproject com en dev topics db sql performing raw queries http
  • 在平板电脑模式下在最上面启动另一个应用程序

    当我从应用程序运行另一个 exe 时 它 在后台启动 并且不会在屏幕顶部显示该应用程序 而是显示平板电脑模式主屏幕 它在正常桌面模式下工作正常 但当我在 Windows 10 平板电脑模式下运行它时它不会显示在顶部 而是在后台启动 我用过m
  • 什么是UUID?

    嗯 什么是一 它是唯一标识某物的标识号 这个想法是 id 号码将是普遍地独特的 因此 任何两个事物都不应该具有相同的 uuid 事实上 如果您要生成 10 万亿个 uuid 则两个 uuid 相同的概率为 0 00000006
  • 模块自动加载就意味着可靠吗?

    环境 我有以下文件夹结构 用于保存 powershell 模块 C PsModules util util psm1 this contains implementation of Test Function util test ps1 f
  • 将枚举值映射到 TypeScript 中的各个类型

    我有一段 TypeScript 代码 如下所示 enum EventType EVENT A eventA EVENT B eventB more event types interface Event type EventType int
  • 在 Android 上开发电子邮件客户端应用程序

    我正在尝试开发一个用于在Android平台上发送和接收电子邮件的小应用程序 目前我一直在使用 Javamail api 尝试发送电子邮件 但是我想 如果我使用 javamail 实现我的应用程序 我将如何接收电子邮件并从我的应用程序收到我已
  • 一个 python 脚本可以同时运行 python 2.x 和 python 3.x

    我有数千台服务器 linux 有些只有 python 2 x 有些只有 python 3 x 我想编写一个脚本 check py 可以在所有服务器上运行 就像 check py 一样 无需使用 python check py 或 pytho
  • 如何将 Azure Active Directory 身份验证添加到 Razor Pages 应用程序?

    据我了解 您可以通过执行 新建项目 gt ASP NET Core Web 应用程序 gt 提供应用程序名称 gt Web 应用程序 在 Visual Studio 2019 中创建 Razor Pages 应用程序 以下教程演示如何将 A
  • 删除整数中的重复数字[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我在技术回合中遇到过这个程序 他们给了我这个程序来删除给定整数中的重复数字不使用数组或字符串 Example int i 12313425
  • jquery change() 警报一键触发 6 次?

    jQuery document ready function c5sliderSelect change function alert change clicked 当我更改选择列表项时 我收到 6 条警报 不知道为什么 我的标记中只有一个
  • JTable 中特定列的比较器

    如何为 JTable 中的特定列设置自定义比较器 我的表的第三列包含双精度值的字符串表示形式 我想为该列创建一个比较器 以便当我单击该列的标题时 它将根据该比较器进行排序 第一个问题是 如果您正在管理双打 为什么您正在处理字符串 如果您使用
  • 防止 Backbone.js 模型在首次添加到集合时进行验证

    首次创建新模型时 有没有办法在 Backbone js 中抑制模型验证 在我的应用程序中 我有一个包含任意数量模型的集合 这些模型表示为列表项 用户可以单击每个项目上的按钮 这会在当前项目下方插入一个新的空项目 显然 空项目未通过验证 因为
  • 如何将 IPV6 地址转换为 IPV4 地址?

    我有使用 IPv4 地址的应用程序 它存储它们很长 因此它只理解 IPv4 地址 是否可以使用Java将IPv6地址转换为IPv4地址 While IPv4 地址范围有 IPv6 等效项 https en wikipedia org wik
  • archiveBaseName 应用于所有构建类型

    我有以下应用程序build gradle android compileSdkVersion 23 buildToolsVersion 23 0 1 defaultConfig applicationId io gresse hugo an
  • 使用 const 断言,如何从任意嵌套对象中提取文字类型?

    这个问题是后续问题this one https stackoverflow com q 76288737 6923555 其中我有一个深度为 2 的结构 const grandkids Karen Ava Alice Amelia Emma
  • 预约和行项目

    我正在构建一个管理应用程序来帮助管理我的移动汽车美容公司 希望还有其他公司 我正在努力弄清楚如何对某些数据进行建模 这个问题与我之前发布的问题相关 但我在下面转载了相关信息 数据库设计 谷歌应用引擎 https stackoverflow
  • 签名字段中的“锁定”字典是签名后签名损坏的原因

    在 PDFBox 2 x 中我把 Lock字典到签名字段 import org apache pdfbox cos COSDictionary import org apache pdfbox cos COSName import org