将数字签名插入现有的 pdf 文件 [英] Insert digital signature into existing pdf file

查看:33
本文介绍了将数字签名插入现有的 pdf 文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用 rails 应用程序服务器将数字签名插入到现有的 pdf 文件中.(基本上,客户端上传pdf文件,服务器使用本地证书对其进行签名)

I need to insert a digital signature into already existing pdf files, using a rails application server. (Basically, clients upload pdf files and the server signs them with a local certificate)

我一直在使用 JSignpdf 将数字签名插入到 pdf 文件中,并开始探索 ruby​​ 的 gems...

I've been using JSignpdf to insert digital signatures into pdf files, and started probing for gems for ruby...

我在 ruby​​pdf 网站上找到了另一个可移植文件来完成这项工作 http://soft.rubypdf.com/software/pdf-digital-signe,但在 ruby​​ 中找不到任何 gem 甚至示例代码来执行此操作.

I've found another portable file to do this job on rubypdf site http://soft.rubypdf.com/software/pdf-digital-signe, but cannot find any gem or even example code to do this in ruby.

我还查看了使用 OpenSSL 进行数字签名验证,但无法'不了解如何使用本地证书文件实际签署现有文档.

I've looked also at Digital signature verification with OpenSSL, but couldn't understand how to actually sign an already existing document, with a local certificate file.

我还在 http://code.google.com/p/origami-pdf/ ,但这对于一个看似简单"(至少在概念上)的任务来说似乎有点苛刻.

I also took a peak at http://code.google.com/p/origami-pdf/ , but this seems a bit harsh for a supposingly "simple" (at least in concept) task.

有什么想法/建议吗?

谢谢

推荐答案

经过一番研究,反复到 OpenSSL 文档 并探索 折纸解决方案,我构建了下面的代码,并设法将本地生成的签名/证书插入到 pdf 文档中.现在我只需要弄清楚如何将它与外部生成的证书一起使用(检查下面的版本 2,我在哪里解决了它).我打开了一个新的问题,您可以在其中找到有关我在使用 OpenSSL 时遇到的困难的一些详细信息和 DER 编码证书.

After some research, recurring to the OpenSSL documentation and exploring the Origami solution, i built the code below, and managed to insert a locally generated signature/certificate into a pdf document. Now I just need to figure out how to use this with an external generated certificate (check version 2 below, where i solved it). I've opened a new question where you can find some details on a difficulty i had with OpenSSL and DER encoded certificates.

为了开发第 2 版,我还花了一些时间想知道如何添加注释 - 使签名在 Adob​​e 阅读器中可见 - 而不向文档添加新页面.从 折纸文档,我找到了 get_page 方法,它解决了我的最后一个问题.我正在使用 Adob​​e Reader X,作为记录.

To develop version 2, i also spent some time wondering how to add an annotation - so the signature becomes visible in Adobe reader - without adding a new page to the document. From origami documentation, i found the get_page method, which solved my last problem on this. I'm using Adobe Reader X, for the record.

希望你觉得这对我有用;-)

Hope you find this useful as I will ;-).

VERSION 1 - 生成证书和密钥文件,并直接插入到文档中

require 'openssl'

begin
  require 'origami'
rescue LoadError
  ORIGAMIDIR = "C:RailsInstallerRuby1.9.3lib
ubygems1.9.1gemsorigami-1.2.4lib"
  $: << 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 => "myemail@email.tt", 
  :reason => "Proof of Concept"
)

# Save the resulting file
pdf.save(OUTPUTFILE)

版本 2 - 使用现有证书签署 pdf 文档

require 'openssl'

begin
  require 'origami'
rescue LoadError
  ORIGAMIDIR = "C:RailsInstallerRuby1.9.3lib
ubygems1.9.1gemsorigami-1.2.4lib"
  $: << 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 => "myemail@email.tt", 
  :reason => "Proof of Concept"
)

# Save the resulting file
pdf.save(OUTPUTFILE)

这篇关于将数字签名插入现有的 pdf 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆