經過一番研究,重複到OpenSSL documentation和探索Origami solution,我建立了下面的代碼,並設法將本地生成的簽名/證書插入到pdf文檔中。現在我只需要弄清楚如何將這個與外部生成的證書一起使用(查看下面的版本2,我在哪裏解決了它)。我已經打開了一個新的question,您可以在這裏找到關於我在OpenSSL和DER encoded證書上遇到的困難的一些詳細信息。
制定第2版,我也花了一些時間琢磨如何添加註釋 - 這樣的簽名在Adobe Reader變得可見 - 而無需添加新的頁面到文檔中。從origami documentation,我找到了get_page方法,這解決了我最後一個問題。我正在使用Adobe Reader X進行記錄。
希望對您有所幫助,我會;-)。
VERSION 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)
VERSION 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)
任務只是「假設」簡單,但在各個層面上都有許多警告和複雜性。這就是爲什麼你找不到任何東西的原因之一 - 我懷疑有人會投入大量精力爲Ruby開發一個工業品質的PDF簽名者。如果你可以用某種方式調用外部類,我會爲.NET/Mono建議一些好的組件。 –
嘿@ EugeneMayevski'EldoSCorp,我想SOGETI是用Origami做的,現在我已經把它放在這裏了,稍微研究一下Origami和OpenSSL的領域。請享用。 – MrWater
@MrWater:請您提供一些示例代碼,說明如何使用jSignPDF將數字簽名添加到使用Java的PDF中? – tarekahf