首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PDF/A-3A文档的PAdES LTV签名会产生无效签名

PDF/A-3A文档的PAdES LTV签名会产生无效签名
EN

Stack Overflow用户
提问于 2021-08-16 11:01:06
回答 1查看 673关注 0票数 5

简介

我有一个问题,数字签署PDF文件,已被标记为PDF/A-3A兼容。使用PDFBox (最新版本,2.0.24),我最终得到了Acrobat中的无效签名,而使用iText7 (最新版本),我得到了一个有效的签名。目标是获得符合PAdES LTV的签名。

概述

我的流程如下(包括PDFBox和iText7):

  • 打开PDF,创建签名散列(要签名的数据)
  • 我打电话给第三方服务是为了拿回数字签名
  • 在服务响应中,为了提高LTV质量,我还需要将OCSP和CRL内容嵌入到PDF中。
  • 我将签名嵌入到PDF中。
  • 我将文档保存到内存中,然后重新打开它以嵌入OCSP和CRL。
  • 我嵌入了OCSP和CRL项,分别创建了DSS和VRI字典。
  • 我把PDF保存到磁盘

对于PDFBox,用于签名的代码是这里,OCSP/CRL嵌入的代码是这里。对于iText7,用于签名和OCSP/CRL嵌入的代码是这里

问题所在

现在,这可以用于大多数PDF文件,包括多签名文档。问题在于一个特殊的PDF格式,它是作为PDF/A遵从性创建的,级别3A。

使用PDFBox时,如果我只是在Acrobet中嵌入签名并打开文档,则签名是有效的。如果我还嵌入了OCSP/CRL内容,则签名不再有效。Adobe Acrobat抱怨:

签名无效:文档自签名以来已被更改或损坏。

我还注意到,仅仅通过这样做:

代码语言:javascript
复制
document.load(inputStream);
document.save(outputStream);

我打破了签名。根据我的测试,实际的嵌入并不是问题的真正原因,而只是在嵌入签名并将其保存回磁盘后重新打开PDF的事实。

使用相同的进程(密钥、证书等)通过iText7,我最终在Acrobat中获得了一个有效的LTV签名。

样本PDFs

示例文档为这里。原件包含未签名的文档,然后有两个示例,一个用于PDFBox (在Acrobat中无效),另一个用于iText7 (在Acrobat中有效)。

到目前为止,我的研究表明,PDFBox在签名嵌入后加载PDF时,不知怎么地破坏了元素的顺序。它暗示本期需要加载和保存文档,不过对于所有其他PDF,我做的都是相同的过程,Acrobat不抱怨签名。

我还尝试使用PDFBox 2.1.0-快照和3.0.0-快照,希望这个问题与PDF中元素的排序有关,并且得到了修复。尽管如此,我还是得到了同样的结果。

稍后编辑1

请看后面的编辑2下面,这以后编辑1这里不是一个好主意!

根据下面@mkl所接受的答案,问题是原始PDF文件,其中包含交叉参考表分成几个子部分,而不是一个。这似乎是由生成PDF的服务使用的库(asosPDFfor.NET,Version21.3或更高版本)造成的。

似乎适用于我当前代码的一个解决方法是:

代码语言:javascript
复制
PDDocumentInformation info = pdDocument.getDocumentInformation();
if (info != null && StringUtils.containsIgnoreCase(info.getProducer(), "Aspose")) {
try {
    pdDocument.save(inMemoryStream);
    pdDocument.close();
    pdDocument = PDDocument.load(inMemoryStream.toByteArray());
    inMemoryStream.reset();
} catch (Exception e) {

基本上,如果我检测到文档的生产者是Aspose,我会将文档保存在内存中(通过PDFBox‘pdDocument.save())并将其加载回去。这确保了交叉参考表在内存中的正确写入,并且从那里签名和OCSP+CRL嵌入按预期工作,在Acrobat中产生一个有效的签名。

稍后编辑2

谢谢你@mkl和TilmanHausherr,你说得对。假设使用某个库生成的所有文档都必须自动标准化,这不是一个好主意,因为现有签名将无效。最后,更好的想法是保持代码的原样,并期望得到一个正确构造的PDF。修复所创建的问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-16 16:46:32

这个问题是由原始PDF中的一个错误引起的。您的PDFBox代码以附加模式(即增量更新)进行签名,因此签名版本中也存在错误。您的iText代码不以附加模式登录,而是重写整个PDF;这样做不会产生与原始PDF生成程序相同的错误,因此错误不再出现在签名版本中。Acrobat在使用更新验证签名时对此类问题非常敏感。

误差

PDF初始修订本的交叉参考表不得分割为单独的分节,但如果您的原始PDF已被拆分:

代码语言:javascript
复制
0 75
0000000000 65535 f
0000000018 00000 n
...
0000313374 00000 n
0000313397 00000 n
76 20
0000313419 00000 n
0000313443 00000 n
...
0000846048 00000 n
0000846175 00000 n

类似的情况已经在这个答案这个答案这个答案和其他地方讨论过;您还可以在这些答案中找到一些规范参考。

通常情况下,当遇到PDF中的小问题时,Acrobat通常是相当松懈的。

通常情况下,即除外,除了在经过签名的之后使用集成签名和增量更新对文档进行验证时,在这种情况下,Acrobat通常会认为此类问题可疑,并且无法验证签名,即使它在验证相同的PDF时没有在签名后进行增量更新时也不会抱怨。

在这种危急情况下,您的最后文档包含了经过签名的修订后的增量更新,这是一个包含验证相关信息的更新。

是谁造成了这个错误?

根据你原来的信息字典,它是由"Aspose.PDF for .NET 21.3.0“生成的。已知,早期版本的Aspose.PDF会创建这样错误的交叉引用表(请参阅上面提到的第一个答案的“损坏PDF处理器”一节)。显然,Aspose还没有解决这个问题。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68801701

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档