Openssl 使用adbe.pkcs7.0签署PDF文件

Openssl 使用adbe.pkcs7.0签署PDF文件,openssl,pdf-generation,pkcs#7,Openssl,Pdf Generation,Pkcs#7,我有一个用C编写的PDF生成器,现在我想给它添加数字签名。我从一个最小的PDF开始,用它签名,现在正试图让我自己的程序生成一个Adobe Acrobat Reader将以相同方式解释的文件。我已经检查了这个问题,但是那里的评论似乎得出结论,应该使用iText,而不是自己尝试。我不想那样 更新: 我确实也读过1.7的PDF参考资料和下面链接的“32000”规范,但有时我对参考资料的数量有点迷茫。对我来说,从一个工作示例开始通常是理解所有东西是如何组合在一起的最简单的方法。很抱歉在我的第一篇文章中没

我有一个用C编写的PDF生成器,现在我想给它添加数字签名。我从一个最小的PDF开始,用它签名,现在正试图让我自己的程序生成一个Adobe Acrobat Reader将以相同方式解释的文件。我已经检查了这个问题,但是那里的评论似乎得出结论,应该使用iText,而不是自己尝试。我不想那样

更新: 我确实也读过1.7的PDF参考资料和下面链接的“32000”规范,但有时我对参考资料的数量有点迷茫。对我来说,从一个工作示例开始通常是理解所有东西是如何组合在一起的最简单的方法。很抱歉在我的第一篇文章中没有说清楚

我已经让Acrobat Reader确认文件中有签名,但仍然有问题。在签名面板中,它显示“签名人未知”,而不是使用密钥中的正确名称。打开“签名属性”时,会显示“此签名无效,因为此签名中包含的格式或信息有错误”。在“高级签名属性”中,哈希算法“不可用”

根据AcrobatReader的说法,JSignPdf中的PDF是正确的。告诉它接受我的自签名证书后,它会显示一个漂亮的绿色签名复选框。为了找到所需的最小添加,我已经清除了一个又一个PDF标记,小心地不更改其余标记的偏移量。这将给出与上述相同的“此签名无效…”错误消息,但仍显示“签名者的身份有效”,并将哈希算法显示为“SHA1”

问题是这种差异的原因是什么,是否有任何工具可以更详细地解释什么是错误的

在/Type/Catalog字典中,我有一个/AcroForm。我试着把它放在适当的位置,作为参考,但这没有什么区别。/AcroForm包含/SigFlags 3和/Fields[x0r],其中x是带有/Subtype/Widget的/Type/Annot的id。(将“endobj”移动到“>>”行以节省此处的空间。)

更新:有一些字典,尽管我现在不记得它们的名字,其中“就地”和“参考”是有意义的。特别是1.7规范中的实现说明中有一些,还有一些“规范说此字段是可选的,但实际上是必需的”

我得到的数据与PKCS7中“:messageDigest”标记的数据完全相同。我自己的文件也是如此。因此,我相信这些价值观是正确的

使用相同的证书和密钥,我得到了完全相同的PKCS7数据,当然除了messageDigest和RSA加密十六进制转储。但是,将JSignPdf PKCS7数据复制到我的文件(因为它们的长度完全相同)不起作用,它仍然抱怨没有找到哈希算法。JSignPdf中的PKCS7数据工作正常,但当然给出了错误的校验和。因此,所有与OpenSSL相关的内容都很可能是正确的,问题一定出在PDF标记的某个地方。是否有我遗漏的参考资料,或必须遵循的标记或对象顺序

已解决:此时唯一剩下的要处理的是ByteRange标记的值。第一个长度实际上还可以。但是,第二个偏移量在实现中被1抵消,太小了1。调整这个,我得到了一个绿色的签名复选框

总之,, 您可能有一个一次性问题,请参见答案末尾的粗体段落。如果这不是你的问题,请分享有问题的文件进行分析

首先,,

在尝试以这种格式操作文件之前,请考虑阅读格式规范。

PDF规范是ISO 32000-1(第2部分正在构建中),您可以在Adobe的网站上下载一份免费副本,只需稍作修改(明确说明这不是ISO副本):

(在你的问题文本中间,你表明你确实知道该文档存在,但你也表明你没有正确研究它。)

有关集成PDF签名的第一个概述,请参阅信息安全堆栈交换

详细地 话虽如此,让我们看看您的问题,并为您指出规范中的某些适当部分:

在/Type/Catalog字典中,我有一个/AcroForm。我试着把它放在适当的位置,作为参考,但这没有什么区别。/AcroForm包含/SigFlags 3和/Fields[x0r],其中x是带有/Subtype/Widget的/Type/Annot的id。(将“endobj”移动到“>>”行以节省此处的空间。)

第7.7.2节规定了文件目录

那里的AcroForm字典指定为

AcroForm词典(可选;PDF 1.2)文档的交互式表单(AcroForm)词典(见12.7.2,“交互式表单词典”)

特别是,它没有指定它是否是直接对象。因此,“这没有什么区别”

第12.7.2节规定了交互式形式词典

特别是,

SigFlagsinteger(可选;PDF 1.3)一组标志,用于指定与签名字段相关的各种文档级特征(见表219和12.7.4.5“签名字段”)。默认值:0

1“SignaturesExist”如果设置,则文档至少包含一个签名字段。此标志允许一致性阅读器启用与签名处理相关的用户界面项(如菜单项或按钮),而无需扫描整个文档以查看是否存在签名字段

2“AppendOnly”如果已设置,则文档包含的签名如果以以下方式保存(写入)文件可能会无效:
2 0 obj <<
 /Type /Catalog
 /Pages 3 0 R
 /AcroForm <<
  /Fields [ 8 0 R ]
  /SigFlags 3
  >>
 >> endobj
4 0 obj <<
 /Type /Page
 /Parent 3 0 R
 /Resources <<
  /ProcSet [/PDF /Text]
  /Font << /F1 6 0 R >>
  >>
 /MediaBox [0 0 595 842]
 /Contents 5 0 R
 /Annots [ 8 0 R ]
>> endobj
8 0 obj <<
 /Subtype/Widget
 /T(Signature1)
 /V 7 0 R
 /Type/Annot
 /FT/Sig
 /Rect [ 0 0 0 0 ]
>> endobj
7 0 obj <<
 /Contents <3082031f...>
 /Filter/Adobe.PPKLite
 /Type/Sig
 /ByteRange [ 0 904 2907 527 ]
 /SubFilter/adbe.pkcs7.detached
 /M(D:20160907094326+02'00')
>> endobj 
SHA1_Init(ctx);
SHA1_Update(ctx, buf + offset1, len1);
SHA1_Update(ctx, buf + offset2, len2);
SHA1_Final(digest, ctx);