使用Adobe PKCS#7证书在Origami中签署了PDF验证 [英] Signed PDF verification in Origami with an Adobe PKCS#7 certificate

查看:307
本文介绍了使用Adobe PKCS#7证书在Origami中签署了PDF验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

概述和澄清:

使用折纸,从签名的pdf中提取证书(例如在Adobe Reader中签名),我无法验证签名:

Using origami, extracting a certificate from a signed pdf (signed within e.g. Adobe Reader) I cannot verify the signature:

origami = Origami::PDF.read(File.open('/path/to/file.pdf', 'r'))
pdf_signature = origami.signature[:Contents]
cert = OpenSSL::PKCS7.new(pdf_signature).certificates.first

origami.verify(trusted_certs: [cert]) #=> false

据我所知,这应该始终是正确的.因此,也许Adobe在签署PDF时使用了SHA的不同字节范围?我如何获得该验证工作?

As far as I can tell, this should always be true. So maybe Adobe uses a different byte range that it takes a SHA of when signing the PDF? How do I get that verify to work?

如果有帮助,在仔细折纸母版上的更改后,我可以从storecontext中获得确切的OpenSSL错误:V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY-我想这意味着从X509 :: Store进行设置.

If it's any help, after tiptoing through the changes on origami master, I was able to get the exact OpenSSL error from the storecontext: V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY - I presume it means from the X509::Store it sets up.

完整背景

我正在尝试验证PDF的数字签名.这就是我所拥有的:

I'm trying to verify the digital signature of a PDF. Here's what I've got:

我已使用Adobe Acrobat签名的PDF(尝试过Pro 10和Reader DC)

A PDF that I've signed using Adobe Acrobat (tried both Pro 10 and Reader DC)

密钥是在Acrobat Pro中生成的,我可以访问.p12,或者导出为FDF,PKCS#7或仅导出为证书文件".还尝试通过Apple的钥匙串访问"加载此证书文件",并将其导出为.pem.这与OpenSSL::PKCS7.new(File.read('/path/to/exported.p7c')).certificates.first.to_pem具有相同的结果,与OpenSSL::PKCS7.new(File.read('/path/to/exported.p7c')).certificates.first.to_pem具有相同的结果:

The key was generated in Acrobat Pro, I have access to the .p12, or exporting as FDF, PKCS#7 or just "Certificate File". Have also tried loading this "Certificate File" via Apple's "Keychain Access" and exporting that as a .pem This gives the same result as OpenSSL::PKCS7.new(File.read('/path/to/exported.p7c')).certificates.first.to_pem which gives the same result as:

openssl pkcs7 -print_certs -inform der -in pkcs7file.p7c -out certificate.cer

所以,我很确定我已经正确提取了证书.

So, I'm pretty sure I've extracted the certificate correctly.

此外,我可以验证PDF中是否嵌入了完全相同的证书-

Also, I can verify that exact same certificate is embedded in the PDF -

pdf_signature = origami.signature[:Contents]
OpenSSL::PKCS7.new(pdf_signature).certificates.first.to_pem #=> Same as above

使用折纸gem,我尝试加载证书并尝试验证:

With the Origami gem, I've tried loading the certificate and attempting verification:

cert = OpenSSL::X509::Certificate.new(File.read('/path/to/pem.cer'))
Origami::PDF.read(File.open('/path/to/file.pdf', 'r')).verify(trusted_certs: [cert])

折纸的输出确认文档已签名,但是verify(..)方法返回false.

Origami's output confirms the document has been signed, but the verify(..) method returns false.

请注意,通过

Note that working through the code from this excellent answer works fine, but it only seems to work if you generate the X.509 keypair using openssl (e.g. the ruby-land bindings as per that code). Unfortunately I'm required to use the pre-existing Adobe-blessed signatures from the user's machines.

也就是说,除此以外,我几乎没有束缚.我可以要求用户以其他任何对我们有用的方式导出他们的证书(如果必要,我甚至可以在他们的计算机上运行一些简单的代码),尽管我不必在过程中传输私钥.我不必使用Origami进行验证,但是它必须是从ubuntu服务器上的ruby可以访问的命令.所有用户都在Macs上运行具有最新软件的软件.

That said, aside from this I have very few restraints; I can ask the users to export their certificate in any other way that is useful to us (I can even run some simple code on their machines if necessary), though I mustn't transmit the private key in the procedure. I don't have to use Origami for the verification, but it does have to be a command accessible from ruby on an ubuntu server. The users are all running on Macs with reasonably up-to-date software.

推荐答案

与原始问题相比,我已经走了一些距离,但相差不大:

I've gotten a little further from my original issue, but not by much:

在哈里·费尔班克斯非常有用的答案中,在原始代码中,扩展是最重要的:

In the original code from Harry Fairbanks' very useful answer, the extensions are paramount:


extension_factory = OpenSSL::X509::ExtensionFactory.new
extension_factory.issuer_certificate = cert
extension_factory.subject_certificate = cert

cert.add_extension extension_factory.create_extension('basicConstraints', 'CA:TRUE', true)
cert.add_extension extension_factory.create_extension('keyUsage', 'digitalSignature,keyCertSign')
cert.add_extension extension_factory.create_extension('subjectKeyIdentifier', 'hash')

所以...按照该答案的其余部分,如果将​​证书保存到pemfile中,扩展名也不会被保存.

So... following the rest of that answer, if you save the certificate to a pemfile, the extensions do not also get saved.

我能够创建PDF,使用从Acrobat Reader导出的密钥用Origami对其进行签名,然后执行以下操作:

I was able to create a PDF, sign it with Origami using the key I exported from Acrobat reader, and then do the following:

cert = OpenSSL::PKCS7.new(pdf_signature).certificates.first

origami.verify(trusted_certs: [cert]) #=> false

## ... then run the extension factory snippet above

origami.verify(trusted_certs: [cert]) #=> true

成功!实际上,甚至Adobe Acrobat Reader也很高兴-这与Origami生成的自签名证书无关.

Success! In fact, even Adobe Acrobat Reader was happy - which I couldn't get it to do with the self-signed certificate that Origami generated.

...但是,当我使用Adobe Acrobat Reader使用相同的密钥对文档签名时,对证书执行相同的魔术咒语时,我仍然会从验证调用中获得false.

... however, when I sign the document using Adobe Acrobat Reader, with the same key, perform the same magical incantation on the cert, I still get false from the verify call.

注意:有人告诉我这实际上对某些人有用.不知道为什么对我来说失败了-当我有机会玩的时候,还会再尝试一次.暂时将其标记为已回答!

Note: I have been told that this actually works for some people. Not sure why it failed for me - when I have a chance to play, will give it another go. Will mark this as answered for now!

这篇关于使用Adobe PKCS#7证书在Origami中签署了PDF验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆