我试图为 PDF 文件的数字签名创建一个开源库。
参数错误
我完成了大部分工作,但我有一个问题,签名显示以下错误:
Error during signature verification.
Adobe Acrobat error.
Bad parameter.
我已经创建了 2 个 pdf 文件,这些文件是几乎所有其他数据的条带,除了所需的信息。
有没有人知道这个错误可能源于哪里?我已经尝试了不同的在线和离线验证器,但它们都没有指向正确的方向。有没有人知道这个错误是否可能源于证书而不是 pdf 结构本身?
字节范围无效
在创建这篇文章时,我也在其他 pdf 文件上测试了它,但得到了错误:
Error during signature verification.
Unexpected byte range values defining scope of signed data.
Details: The signature byte range is invalid
请注意,pdf 的一部分将其描述为:
...
/SubFilter/adbe.pkcs7.detached
/ByteRange[0 4197 22193 30080 ]
/Contents<30820...
我已经多次重新计算了ByteRange
属性,甚至尝试在每个方向上将其更改一个字节,但这总是会导致Signature processing error.
。我不知道ByteRange
还有什么不正确的。(添加的空格与 Acrobat 填充字节的方式相同。)
如果有人可能有什么问题可能是一个想法,让我知道。
文件
这是我的结果文件:
result_bad_param_with_image.pdf (mirror1) (mirror2)
result_bad_param_no_image.pdf (mirror1) (mirror2)
result2_invalid_byte_range_with_image.pdf (mirror1) (mirror2)
result2_invalid_byte_range_no_image.pdf (mirror1) (mirror2)
签名文件(与 PDF 中的Contents
字段相同,但直接在单独的文件中除外):
signature.der
的内容打印在这里:https://pastebin.com/W4EGJ2fX(使用openssl cms -inform DER -in signature.der -cmsout -print
命令)
(我知道签名是自签名的,不包含很多信息,但这不应该是这个问题,我认为,这只是为了创建这些例子)
编辑:解决了一些问题并添加了一些额外文件后的新链接:
result.pdf signature.der signed_content.der您的签名中存在一些错误,并且在数字签名的情况下,不常见的结构可能会导致验证程序拒绝。
签名容器内的签名哈希值不正确
在具有签名属性的 CMS 签名容器中签名使用两个哈希值:
PDF 的带符号字节范围的哈希值;该值在您的示例文件中是正确的;
签名容器的SignerInfo
中已签名属性的哈希值;该值在示例文件中不正确。
PS:再次查看不匹配,结果发现您的签名属性不是 DER 编码的:DER 编码特别是按特定顺序对 SET 的元素进行排序,在您的情况下,属性顺序不是 DER 顺序。
PPS:在评论中,您认为
我刚刚检查了 SET 的顺序,我找不到任何错误的东西。这是我的推理,让我知道什么部分是不正确的。
首先,这种推理是有缺陷的:所讨论的类型是集合类型(更确切地说是 ASN.1 SET OF),而不是某种映射类型;DER 编码规则集只知道 ASN.1 基本类型。
事实上,快速浏览规范显示:
11.6 组件集
一组值的分量值的编码应按升序显示,编码作为八位字节字符串进行比较,较短的分量在其尾端用 0 个八位字节填充。
注意-填充八位字节仅用于比较目的,不会出现在编码中。
(ISO / IEC 8825-1 / ITU-T Rec.X.690,第 11 节“CER 和 DER 使用的 BER 限制”)
因此,在有符号属性的情况下,您首先对属性元素进行 DER 编码,然后如上所述对结果字节数组进行排序。
顺便说一句,您的签名问题只会导致大约一半的验证程序出现问题。一些验证程序不检查或 DER 重新编码签名的属性,因此它们会获得与您相同的哈希值。其他人则可以预先检查编码(因此,由于问题而抛出错误),也可以简单地在 DER 中重新编码属性(因此,获得与您不同的哈希值)。
签名者证书的扩展密钥用法有问题
您的签名者证书具有扩展密钥使用值 1.3.6.1.4.1.311.80.1(Microsoft 用于文档加密的 OID)。Adobe 验证用于仅支持没有扩展密钥使用或具有以下一项或多项的证书:
emailProtection
codeSigning
anyExtendedKeyUsage
1.2.840.113583.1.1.5 (Adobe Authentic Documents Trust)
SeeEnterprise Toolkit » Digital Signatures Guide for IT » A:Changes Across Releases.增量更新不正确
您登录到原始 PDF 的增量更新。这通常是一个好主意,因为它允许提取未签名的原始文档。
但是需要正确添加增量更新,并且在result2_invalid_byte_range_no_image.pdf和result2_invalid_byte_range_with_image.pdf的情况下,它做得不正确:原始修订是使用交叉引用表创建的,但是您的增量更新使用纯交叉引用流。
当打开混合使用交叉引用表和纯交叉引用流的文档时,Adobe Acrobat 会在内部修复此问题,特别是重新定位签名,从而使字节范围不正确。
不常见的签名字段结构
您在示例 PDF 中使用不常见的签名字段结构,您将小部件与字段分开,并且在签名中仅更新字段,而不是小部件。
虽然这严格来说是可以的,我会实现共同的结构,同时使代码工作,只有在此后偏离。
PS:在评论中,您问我是否可以对此进行详细说明。
您的签名实现在第一步中添加了一个带有空签名字段的增量更新和一个小部件作为间接引用的孩子,例如:
16 0 obj
<<
/Type /Annot
/F 4
/Subtype /Widget
/BS << /Type /Border /S /S /W 0 >>
/Parent 17 0 R
/P 2 0 R
/Rect [141.75 664.89 276.75 702.39]
/AP << /N 18 0 R >>
/MK << /BC [.1882353 .1882353 .1882353] /BG [1.00 1.00 1.00] /R 0 >>
/DA (/TiRo 0 Tf 0 0 0 rg\r
)
>>
endobj
17 0 obj
<<
/Kids [16 0 R]
/FT /Sig
/T (eyJ1c2VySWQiOiIyNzIifQ==)
>>
在另一个增量更新中,您可以使用直接签名值对字段进行签名,但不要更改小部件,例如:
17 0 obj
<<
/Kids [16 0 R]
/FT /Sig
/T (eyJ1c2VySWQiOiIyNzIifQ==)
/V << /Type/Sig ... >>
>>
这在某些方面并不常见:
通常对于签名,使用合并字段和小部件的选项。
通常对于签名(除了使用权签名),签名字典不是密钥V的直接值,而是间接值。
通常,如果存在外观,则签名字段的外观将与签名字典一起更新。
此外,除非在添加空签名字段和对其进行签名之间发生其他表单填写,否则通常会在同一文档更新中添加和填写字段。
因此,更常见的是一个单一的增量更新(甚至完全重新保存)包含这样的东西:
92 0 obj
<<
/AP << /N 94 0 R >>
/DA (/MyriadPro-Regular 0 Tf 0 Tz 0 g)
/F 132
/FT /Sig
/MK <<>>
/P 1 0 R
/Rect [117.575 499.561 515.968 520.938]
/Subtype /Widget
/T (Signature3)
/Type /Annot
/V 93 0 R
>>
endobj
93 0 obj
<<
/ByteRange [ 0 3227714 5751810 2789]
...
>>
如上所述,不过,您的结构严格来说也是可以的。但是“Bad 参数”仅在从文档中的小部件或签名面板进行验证时出现,但在使用“签名属性”对话框的“验证签名”按钮验证签名时不会出现。因此,我认为 Adobe 可能会被一个不常见的结构所激怒。
本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处
评论列表(83条)