概述和澄清:
使用折纸,从签名的pdf中提取证书(例如在Adobe Reader中签名),我无法验证签名:
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的不同字节范围?我如何获得该验证工作?
如果有任何帮助,在仔细折纸母版上的更改后,我可以从storecontext中获得确切的OpenSSL错误:V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY-我想这意味着从X509 :: Store进行设置。
完整背景
我正在尝试验证PDF的数字签名。这就是我所拥有的:
我已使用Adobe Acrobat签名的PDF(尝试过Pro 10和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 -print_certs -inform der -in pkcs7file.p7c -out certificate.cer
所以,我很确定我已经正确提取了证书。
此外,我可以验证PDF中是否嵌入了完全相同的证书-
pdf_signature = origami.signature[:Contents]
OpenSSL::pkcs7.new(pdf_signature).certificates.first.to_pem #=> Same as above
使用折纸gem,我尝试加载证书并尝试验证:
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。
请注意,通过this excellent answer中的代码可以正常工作,但是,仅当您使用openssl生成X.509密钥对时(例如,按照该代码进行的ruby-land绑定),它才似乎有效。不幸的是,我需要使用用户计算机中预先存在的Adobe祝福签名。
也就是说,除此之外,我的束缚很少。我可以要求用户以其他对我们有用的方式导出证书(即使必要时,我甚至可以在其计算机上运行一些简单的代码),尽管我不必在过程中传输私钥。我不必使用Origami进行验证,但是它必须是从ubuntu服务器上的ruby可以访问的命令。所有用户都在Macs上运行具有相当最新软件的软件。