Вставить цифровую подпись в существующий файл pdf

Мне нужно вставить цифровую подпись в уже существующие pdf файлы, используя сервер приложений rails. (В принципе, клиенты загружают PDF файлы, а сервер подписывает их локальным сертификатом)

Я использую JSignpdf для вставки цифровых подписей в pdf файлы и начинал исследование камней для рубинов...

Я нашел еще один переносимый файл, чтобы выполнить эту работу на сайте rubypdf http://soft.rubypdf.com/software/pdf-digital-signe, но не может найти какой-либо камень или даже пример кода для этого в рубине.

Я также посмотрел на проверку цифровой подписи с помощью OpenSSL, но не смог понять, как фактически подписать уже существующий документ, с локальным файлом сертификата.

Я также взял пик на http://code.google.com/p/origami-pdf/, но это кажется немного суровым для предполагаемого "простого" (по крайней мере, в концепции).

Любые идеи/предложения?

Спасибо

Ответ 1

После некоторых исследований, повторяющихся в документации OpenSSL и изучении Решение Origami, я создал код ниже и смог вставить локально сгенерированную подпись/сертификат в документ PDF. Теперь мне просто нужно выяснить, как использовать это с внешним сгенерированным сертификатом (проверьте версию 2 ниже, где я ее решил). Я открыл новый question, где вы можете найти некоторые подробности о сложности, с которыми я столкнулся в OpenSSL и DER закодированы.

Чтобы разработать версию 2, я также потратил некоторое время на то, как добавить аннотацию, поэтому подпись становится видимой в Adobe Reader - без добавления новой страницы в документ. Из документация оригами, я нашел метод get_page, который решил мою последнюю проблему. Я использую Adobe Reader X для записи.

Надеюсь, вы сочтете это полезным, как я, -).

ВЕРСИЯ 1 - Создайте сертификат и файл ключа и вставьте их непосредственно в документ

require 'openssl'

begin
  require 'origami'
rescue LoadError
  ORIGAMIDIR = "C:\RailsInstaller\Ruby1.9.3\lib\ruby\gems\1.9.1\gems\origami-1.2.4\lib"
  $: << ORIGAMIDIR
  require 'origami'
end
include Origami

# Code below is based on documentation available on
# http://www.ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL.html
key = OpenSSL::PKey::RSA.new 2048

open 'private_key.pem', 'w' do |io| io.write key.to_pem end
open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end

cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
pass_phrase = 'Origami rocks'

key_secure = key.export cipher, pass_phrase

open 'private_key.pem', 'w' do |io|
  io.write key_secure
end

#Create the certificate

name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'

cert = OpenSSL::X509::Certificate.new
cert.version = 2
cert.serial = 0
cert.not_before = Time.now
cert.not_after = Time.now + 3600

cert.public_key = key.public_key
cert.subject = name


OUTPUTFILE = "test.pdf"

contents = ContentStream.new.setFilter(:FlateDecode)
contents.write OUTPUTFILE,
  :x => 350, :y => 750, :rendering => Text::Rendering::STROKE, :size => 30

pdf = PDF.read('Sample.pdf')


# Open certificate files

#sigannot = Annotation::Widget::Signature.new
#sigannot.Rect = Rectangle[:llx => 89.0, :lly => 386.0, :urx => 190.0, :ury => 353.0]

#page.add_annot(sigannot)

# Sign the PDF with the specified keys
pdf.sign(cert, key, 
  :method => 'adbe.pkcs7.sha1',
  #:annotation => sigannot, 
  :location => "Portugal", 
  :contact => "[email protected]", 
  :reason => "Proof of Concept"
)

# Save the resulting file
pdf.save(OUTPUTFILE)

ВЕРСИЯ 2 - Использовать существующие сертификаты для подписи документа PDF

require 'openssl'

begin
  require 'origami'
rescue LoadError
  ORIGAMIDIR = "C:\RailsInstaller\Ruby1.9.3\lib\ruby\gems\1.9.1\gems\origami-1.2.4\lib"
  $: << ORIGAMIDIR
  require 'origami'
end
include Origami

INPUTFILE = "Sample.pdf"
@inputfile = String.new(INPUTFILE)
OUTPUTFILE = @inputfile.insert(INPUTFILE.rindex("."),"_signed")
CERTFILE = "certificate.pem"
RSAKEYFILE = "private_key.pem"
passphrase = "your passphrase"

key4pem=File.read RSAKEYFILE

key = OpenSSL::PKey::RSA.new key4pem, passphrase
cert = OpenSSL::X509::Certificate.new(File.read CERTFILE)

pdf = PDF.read(INPUTFILE)
page = pdf.get_page(1)

# Add signature annotation (so it becomes visibles in pdf document)

sigannot = Annotation::Widget::Signature.new
sigannot.Rect = Rectangle[:llx => 89.0, :lly => 386.0, :urx => 190.0, :ury => 353.0]

page.add_annot(sigannot)

# Sign the PDF with the specified keys
pdf.sign(cert, key, 
  :method => 'adbe.pkcs7.sha1',
  :annotation => sigannot, 
  :location => "Portugal", 
  :contact => "[email protected]", 
  :reason => "Proof of Concept"
)

# Save the resulting file
pdf.save(OUTPUTFILE)

Ответ 2

Если вы работаете над проектом за плату, вы можете рассмотреть jPDFSecure, коммерческую библиотеку Java, созданную для разработчиков для цифровой подписи документов PDF и изменения настроек безопасности в документах PDF. С помощью jPDFSecure ваше приложение или java-апплет могут шифровать документы PDF, устанавливать разрешения и пароли, а также создавать и применять цифровые подписи. jPDFSecure оптимизирован для повышения производительности и построен на основе запатентованной технологии PDF Qoppa, поэтому нет необходимости в каком-либо стороннем программном обеспечении или драйверах.

jPDFSecure имеет простой интерфейс для загрузки PDF-документов из файлов, сетевых дисков, URL-адресов и даже входных потоков, которые могут генерироваться во время выполнения или поступать напрямую из базы данных. После изменения параметров безопасности jPDFSecure может сохранить документ в файл, java.io.OutputStream или javax.servlet.ServletOutputStream при запуске на сервере приложений Java EE, чтобы вывести файл непосредственно в браузер.

jPDFSecure не зависит от платформы и может использоваться в любой среде, поддерживающей Java, включая Windows, Mac OSX и Linux.