Проверка подписи PDF в Origami с сертификатом Adobe PKCS # 7 - PullRequest
1 голос
/ 08 ноября 2019

Обобщены и уточнены:

Используя оригами, извлекая сертификат из подписанного 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? Как мне заставить эту проверку работать?

Если это поможет, после того, как я на цыпочках прошел через изменения в оригами-мастере, я смог получить точную ошибку OpenSSL из storecontext: V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY - я предполагаю, что это означает изX509 :: Магазин настроен.


Полный фон

Я пытаюсь проверить цифровую подпись PDF. Вот что у меня есть:

PDF, который я подписал с помощью Adobe Acrobat (пробовал и Pro 10, и Reader DC)

Ключ был сгенерирован в Acrobat Pro, у меня есть доступ к.p12, или экспорт в формате FDF, PKCS # 7 или просто «Файл сертификата». Я также пытался загрузить этот «файл сертификата» через Apple Keychain Access и экспортировать его как .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

С гемом Origami япопытался загрузить сертификат и попытаться подтвердить:

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])

Вывод Origami подтверждает, что документ был подписан, но метод verify(..) возвращает false.

Обратите внимание, что при работе с кодом из этот превосходный ответ работает отлично, но, похоже, он будет работать, только если вы сгенерируете пару ключей X.509 с помощью openssl (например, привязки ruby-land согласно этому коду). К сожалению, я должен использовать уже существующие подписанные Adobe благословения на компьютерах пользователей.

Тем не менее, помимо этого у меня очень мало ограничений;Я могу попросить пользователей экспортировать свой сертификат любым другим удобным для нас способом (при необходимости я даже могу запустить простой код на их компьютерах), хотя я не должен передавать закрытый ключ в процедуре. Мне не нужно использовать Origami для проверки, но это должна быть команда, доступная из ruby ​​на сервере Ubuntu. Все пользователи работают на Mac с достаточно современным программным обеспечением.

Ответы [ 2 ]

1 голос
/ 11 ноября 2019

Я немного продвинулся от своего первоначального выпуска, но ненамного:

Сертификаты требуют правильных расширений

В исходном коде от Harry Fairbanks 'очень полезноответ, расширения имеют первостепенное значение:


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-файл, подписать его с помощью Origami с помощью ключа, который я экспортировал из программы чтения Acrobat, а затем выполнить следующие действия:

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.

... однако, когда я подписываю документ с помощью Adobe Acrobat Reader,с помощью того же ключа выполните то же магическое заклинание на сертификате, я все еще получаю false от звонка проверки.


Примечание: мне сказали, что это действительно работает для некоторых людей. Не уверен, почему это не удалось для меня - когда у меня будет возможность сыграть, еще раз. Отметит это как ответ на данный момент!

0 голосов
/ 10 ноября 2019

Возможно, шифры разные. Может случиться так, что шифр Adobe будет отличаться от того, который использует openssl, и тогда он не пройдет проверку проверки. Взгляните на это. Подробная информация о шифрах

Это также может быть полезно команды openssl

...