概述和澄清:
使用折纸,从签名的pdf (例如Adobe内签名)中提取证书,我无法验证签名:
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?我要怎么做才能证明这一点呢?
如果这有什么帮助的话,在完成了对折纸大师的更改之后,我能够从存储上下文中获得确切的OpenSSL错误: V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY --我猜想它的意思是从X 509::存储它设置的。
全背景
我在验证PDF的数字签名。我要说的是:
我用Acrobat签署的PDF (试过Pro 10和Reader DC)
密钥是在Acrobat中生成的,我可以访问.p12,或者导出为FDF、PKCS#7或仅仅是“证书文件”。还尝试通过苹果的“密钥链访问”加载此“证书文件”,并将其作为.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通过使用折纸宝石,我尝试加载证书并尝试验证:
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。
请注意,通过这个极好的答案编写的代码运行良好,但只有使用openssl生成X.509键区(例如,根据该代码生成的红宝石绑定),它才能正常工作。不幸的是,我需要使用来自用户机器的预先存在的Adobe认证签名。
尽管如此,除此之外,我没有什么限制;我可以要求用户以对我们有用的任何其他方式导出他们的证书(如果有必要,我甚至可以在他们的机器上运行一些简单的代码),尽管我不能在过程中传输私钥。我不需要使用Origami进行验证,但是它必须是一个命令,可以从ubuntu服务器上的ruby访问。所有的用户都在Mac上运行,使用的是合理的最新软件。
发布于 2019-11-11 17:17:50
我已经离我最初的问题更远了一点,但并没有太多:
证书需要正确的扩展
在原始代码哈利·费尔班克斯非常有用的答案,中,扩展是最重要的:
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,则扩展名也不会被保存。
我能够创建一个PDF,使用我从Acrobat阅读器导出的键用Origami签名,然后执行以下操作:
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成功!事实上,甚至也很高兴--我无法让它与折纸生成的自签名证书联系起来。
..。但是,当我使用Acrobat签署文档时,使用相同的密钥在证书上执行相同的魔法咒语,我仍然可以从验证调用中获得false。
注:有人告诉我,这实际上适用于某些人。不知道为什么对我来说失败了--当我有机会上场的时候,我会再给它一次机会。就像现在回答的那样!
https://stackoverflow.com/questions/58769162
复制相似问题