2012-08-22 233 views
11

Necesito insertar una firma digital en archivos PDF ya existentes, utilizando un servidor de aplicaciones de rieles. (Básicamente, los clientes cargar archivos PDF y el servidor de los firma con un certificado local)Insertar firma digital en el archivo pdf existente

He estado usando JSignPdf para insertar firmas digitales en archivos PDF, y comenzó a sondear en busca de gemas de rubí ...

I He encontrado otro archivo portátil para hacer este trabajo en el sitio rubypdf http://soft.rubypdf.com/software/pdf-digital-signe, pero no puedo encontrar ninguna gema o código de ejemplo para hacer esto en ruby.

Miré también en Digital signature verification with OpenSSL, pero no pude entender cómo firmar realmente un documento ya existente, con un archivo de certificado local.

También hice un pico en http://code.google.com/p/origami-pdf/, pero esto parece un poco duro para una tarea supuestamente "simple" (al menos en concepto).

¿Alguna idea/sugerencia?

Gracias

+1

La tarea es solo "supuestamente" simple, pero tiene muchas salvedades y complejidades en todos los niveles. Esa es una de las razones por las que no se puede encontrar nada. Dudo que se invierta un esfuerzo significativo en el desarrollo de un firmante de PDF de calidad industrial para Ruby. Sugeriría un par de buenos componentes para .NET/Mono si puede llamar a clases externas de alguna manera. –

+0

Hola @ EugeneMayevski'EldoSCorp, supongo que SOGETI lo hizo con Origami, y ahora lo he puesto aquí, después de explorar los reinos de Origami y OpenSSL por un tiempo. Disfrutar. – MrWater

+0

@MrWater: ¿podría proporcionarnos algún código de muestra que muestre cómo puede usar jSignPDF para agregar firmas digitales a su PDF utilizando Java? – tarekahf

Respuesta

11

Después de algunas investigaciones, recurriendo al OpenSSL documentation y explorando el Origami solution, construí el siguiente código y logré insertar una firma/certificado generado localmente en un documento pdf. Ahora solo necesito descubrir cómo usar esto con un certificado generado externamente (verifique la versión 2 a continuación, donde lo resolví). Abrí un nuevo question donde puede encontrar algunos detalles sobre una dificultad que tuve con los certificados OpenSSL y DER encoded.

Para desarrollar la versión 2, también pasé un tiempo preguntándome cómo agregar una anotación, para que la firma se vuelva visible en el lector de Adobe, sin agregar una página nueva al documento. Desde origami documentation, encontré el método get_page, que resolvió mi último problema al respecto. Estoy usando Adobe Reader X, para el registro.

Espero que encuentres útil esto como lo haré ;-).

VERSIÓN 1 - Generar certificado y archivo de clave, e insertarlos directamente en el documento

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) 

Versión 2 - Uso existente certificados para firmar un documento 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) 
+0

Tengo requisitos similares pero estoy usando Java. Creo que jSignPDF o jPDFSecure deberían hacerlo. Me gustaría saber qué biblioteca ha usado para agregar firma/certificado digital a PDF. – tarekahf

+0

@MrWater esto me da 'method_missing ': Ningún método' add_annot' para Origami :: Page (NoMethodError). ¿Tiene alguna pista de cuál podría ser el motivo del error? – ManuKaracho

+1

@tarekahf solo ahora que vi esto. Si recuerdo (esto fue en 2012) estaba usando la aplicación Jsignpdf, no lib, por lo que no puedo responderte directamente. Tal vez deberías probar y verificar cómo usar la línea de comando con 'java -jar JSignPdf.jar --help' como se indica en http://jsignpdf.sourceforge.net/ y quizás de alguna manera llamar a la línea de comando desde tu aplicación. – MrWater

-2

Si está trabajando en un proyecto para el pago, es posible que desee considerar jPDFSecure, una biblioteca de Java comercial que se construye para los desarrolladores para firmar digitalmente documentos PDF y cambiar la configuración de seguridad en documentos PDF. Con jPDFSecure, su aplicación o applet de Java puede cifrar documentos PDF, establecer permisos y contraseñas, y crear y aplicar firmas digitales. jPDFSecure está optimizado para el rendimiento y se basa en la tecnología PDF patentada de Qoppa, por lo que no es necesario ningún software o controlador de terceros.

jPDFSecure tiene una interfaz simple para cargar documentos PDF desde archivos, unidades de red, URL e incluso flujos de entrada, que se pueden generar en tiempo de ejecución o provienen directamente de una base de datos. Después de cambiar la configuración de seguridad, jPDFSecure puede guardar el documento en un archivo, java.io.OutputStream o javax.servlet.ServletOutputStream cuando se ejecuta en un servidor de aplicaciones Java EE para generar el archivo directamente en un navegador.

jPDFSecure es independiente de la plataforma y se puede usar en cualquier entorno que admita Java, incluidos Windows, Mac OSX y Linux.

+1

¿Y cómo voy a integrar esto con ruby? ¿Por qué jPDFSecure sería mejor que jSignpdf? – MrWater

Cuestiones relacionadas