Ruby 如何使pdf签名可见(以及有效性图标)
最初的问题是如何使用Ruby使pdf签名可见。我现在可以用下面的代码来做 我现在唯一的问题是有效性图标。它出现了,但不是(我现在用席) 这就是我现在拥有的Ruby 如何使pdf签名可见(以及有效性图标),ruby,pdf,digital-signature,visible,Ruby,Pdf,Digital Signature,Visible,最初的问题是如何使用Ruby使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" $: << ORIGAMID
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
def draw_signature(name, attr = {})
load! if @instructions.nil?
x, y = attr[:x], attr[:y]
@instructions << PDF::Instruction.new('q')
@instructions << PDF::Instruction.new('cm', 1, 0, 0, 1, x, y)
@instructions << PDF::Instruction.new('Do', name)
@instructions << PDF::Instruction.new('Q')
end
def SignPdf(inputF)
@inputfile = String.new(inputF)
outputF = @inputfile.insert(inputF.rindex("."),"_signed8")
certFile = "cert.pem"
rsakeyFile = "pk.pem"
passphrase = "mypass"
key4pem=File.read rsakeyFile
key = OpenSSL::PKey::RSA.new key4pem, passphrase
cert = OpenSSL::X509::Certificate.new(File.read certFile)
pdf = PDF.read(inputF)
page = pdf.get_page(1)
#signature image
imageobject = Origami::Graphics::ImageXObject.from_image_file('c:\rails_projects\RecibosOnline\app\assets\images\logo.jpg', 'jpg')
imageobject.Width = 200
imageobject.Height = 141
#formobject = Origami::Graphics::FormXObject.new
#formobject.write("Teste")
width = 300
height=141
x=201
y=186
signedby = "My Company"
location = "Portugal"#pdf.signature[pdf.signature.keys[5]]
contact = "mail@mail.com" #pdf.signature[pdf.signature.keys[6]]
reason = "Testing" #pdf.signature[pdf.signature.keys[7]]
date = Time.now
caption="Digitally Signed By: #{signedby}\nContact: #{contact}\nLocation: #{location}\nReason: #{reason}\nDate: #{date} "
n0 = Annotation::AppearanceStream.new
n0.Type=Origami::Name.new("XObject")
n0.BBox = [ 0, 0, 100, 100 ]
n0.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n0.set_indirect(true)
n0.Resources = Resources.new
n0.Resources.ProcSet = [Origami::Name.new("PDF"),Origami::Name.new("Text"),Origami::Name.new("Text"),Origami::Name.new("ImageB"),Origami::Name.new("ImageC"),Origami::Name.new("ImageI")]
n0.draw_stream('% DSBlank')
#n0.write(Origami::Name.new("% DSBlank"))
n2 = Annotation::AppearanceStream.new
n2.Type = Origami::Name.new("XObject")
#n2.Subtype = Origami::Name.new("Form")
n2.Resources = Resources.new
n2.Resources.ProcSet = [Origami::Name.new("Text")]
n2.set_indirect(true)
n2.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n2.BBox = [ 0, 0, width, height ]
n2.write(caption,:x => 40, :y => height-35, :size => 15)
#n2.draw_stream("q 0 0 198 48 re W n BT /Helv 7.645 Tf 0 g 0 40.135 Td (Digitally ) Tj 28.889 0 Td (signed ) Tj 24.652 0 Td (by ) Tj10.198 0 Td (James ) Tj 24.641 0 Td (Pravetz ) Tj-88.38 -9.174 Td (DN: ) Tj 15.29 0 Td (cn=James ) Tj37.18 0 Td (Pravetz, ) Tj 30.165 0 Td (c=CA, ) Tj 23.156 0 Td0 -9.174 Td (Reason: ) Tj 30.599 0 Td (I ) Tj 4.248 0 Td(have ) Tj 18.702 0 Td (reviewed ) Tj 32.719 0 Td(this ) Tj 14.02 0 Td (document ) Tj -100.288 -9.174 Td(Date: ) Tj 20.397 0 Td (2006.06.08 ) Tj 40.386 0 Td(13:39:35 ) Tj 31.883 0 Td (-07'00') Tj ET Q")
#Sets the root dictionary element
frm = Annotation::AppearanceStream.new
frm.set_indirect(true)
#frm.Type = Origami::Name.new("XObject")
#frm.Subtype = Origami::Name.new("Form")
frm.Resources = Resources.new
frm.Resources.ProcSet = [Origami::Name.new("PDF")]
frm.Resources.add_xobject(Origami::Name.new("n0"), n0)
frm.Resources.add_xobject(Origami::Name.new("n2"), n2)
frm.Matrix = [ 1, 0, 0, 1, 0, 0 ]
frm.BBox = [ 0, 0, width, height ]
frm.draw_stream('q 1 0 0 1 0 0 cm /n0 Do Q')
frm.draw_stream('q 1 0 0 1 0 0 cm /n2 Do Q')
xo17 = Annotation::Widget::Signature.new
#xo17 = Annotation::Widget::Signature.new
xo17.Rect = Rectangle[ llx: x, lly: y, urx: x+width, ury: y+height ]
#xo17.Resources = Resources.new
#xo17.Resources.add_xobject(Origami::Name.new("FRM"), frm)
xo17.F = Annotation::Flags::PRINT #sets the print mode on
xo17.H = Annotation::Widget::Highlight::INVERT
streamN = Annotation::AppearanceStream.new #.setFilter(:FlateDecode)
streamN.set_indirect(true)
streamN.BBox = [ 0, 0, width, height ]
streamN.Resources = Resources.new
streamN.Resources.ProcSet = [Origami::Name.new("PDF")]
streamN.Resources.add_xobject(Origami::Name.new("FRM"), frm)
streamN.Subtype = nil
#cs = ContentStream.new('q 1 0 0 1 0 0 cm /FRM Do Q',streamN)
streamN.draw_stream('q 1 0 0 1 0 0 cm /FRM Do Q')
#streamN.draw_image(Origami::Name.new("FRM"),{x:x,y:y})
#streamN.write(caption,:x => 40, :y => height-35, :size => 15)
xo17.set_normal_appearance(streamN)
# page.add_xobject(Origami::Name.new("FRM"),frm)
# page.add_xobject(Origami::Name.new("n0"),n0)
# page.add_xobject(Origami::Name.new("n2"),n2)
page.add_annot(xo17)
# Sign the PDF with the specified keys
pdf.sign(cert, key,
:method => 'adbe.pkcs7.sha1',
:annotation => xo17,
:location => location,
:contact => contact,
:reason => reason
)
# Save the resulting file
pdf.save(outputF)
end
SignPdf("Sample.pdf")
需要“openssl”
开始
需要“折纸”
救援装载错误
ORIGAMIDIR=“C:\RailsInstaller\Ruby1.9.3\lib\ruby\gems\1.9.1\gems\origami-1.2.4\lib”
$:高度-35,:尺寸=>15)
xo17.设置正常外观(streamN)
#第页添加对象(Origami::Name.new(“FRM”),FRM)
#第页添加对象(Origami::Name.new(“n0”),n0)
#第页添加对象(Origami::Name.new(“n2”),n2)
第页添加注释(xo17)
#使用指定的密钥对PDF进行签名
pdf.签名(证书、钥匙、,
:method=>'adbe.pkcs7.sha1',
:annotation=>xo17,
:location=>location,
:contact=>contact,
:原因=>原因
)
#保存结果文件
pdf.save(outputF)
结束
SignPdf(“Sample.pdf”)
编辑2
在mkl介入之后,我进一步深入了解了源代码
我注意到了这个文件,其中包含以下用于绘制图像的代码
def draw_image(name, attr = {})
load! if @instructions.nil?
x, y = attr[:x], attr[:y]
@instructions << PDF::Instruction.new('q')
@instructions << PDF::Instruction.new('cm', 300, 0, 0, 300, x, y)
@instructions << PDF::Instruction.new('Do', name)
@instructions << PDF::Instruction.new('Q')
end
def draw_image(名称,attr={})
负载如果@instructions.nil?
x、 y=attr[:x],attr[:y]
@说明>
/M(D:20130403131841Z00'00)
/位置
/过滤器/Adobe.PPKMS
/内容
/联系信息
/ByteRange[0 12880 17078 2366]
>>
endobj
18 0 obj
>
>>
/长度27
/子类型/形式
>>溪流
q 1 0 0 1 0 0 cm/FRM Do q
尾流
endobj
19 0 obj
>
>>
/矩阵[10 0 1 0 0]
/BBox[0 300 141]
/长度52
/子类型/形式
>>溪流
q 1 0 0 1 0 0 cm/n0 Do q
q 1 0 0 1 0 cm/n2 Do q
尾流
endobj
20 0 obj
>>
/长度10
/子类型/形式
>>溪流
%DSBlank
尾流
endobj
21 0 obj
>>
/矩阵[10 0 1 0 0]
/BBox[0 300 141]
/长度176
/子类型/形式
>>溪流
英国电信
/F1 15 Tf
40 106 Td
20毫升
(数字签名人:我的公司)Tj
(联系方式:mail@mail.com) '
(地点:葡萄牙)
(理由:测试)"
(日期:2013-04-0314:18:41+0100)
ET
尾流
endobj
22 0 obj
>
endobj
我错过了什么?有时候,一个人只需要知道如何真正理解他一遍又一遍地读到的东西 PPKapearances文件中包含了所有内容。我甚至没有按照他们推荐的词典结构去做我所期望的那样。 我只需要添加n1和n3层,流内容甚至可以是“%DS Blank”。您找到的问号字符串流是我从解决方案的
PdfSignatureAppearance.cs
文件中获取的。如果我使用一个Foxit阅读器,就会显示问号(即使签名有效)。对于Adobe来说,我使用它或DSBlank
都无所谓
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
def draw_signature(name, attr = {})
load! if @instructions.nil?
x, y = attr[:x], attr[:y]
@instructions << PDF::Instruction.new('q')
@instructions << PDF::Instruction.new('cm', 1, 0, 0, 1, x, y)
@instructions << PDF::Instruction.new('Do', name)
@instructions << PDF::Instruction.new('Q')
end
def SignPdf(inputF)
@inputfile = String.new(inputF)
outputF = @inputfile.insert(inputF.rindex("."),"_signed8")
certFile = "cert.pem"
rsakeyFile = "pk.pem"
passphrase = "mypass"
key4pem=File.read rsakeyFile
key = OpenSSL::PKey::RSA.new key4pem, passphrase
cert = OpenSSL::X509::Certificate.new(File.read certFile)
pdf = PDF.read(inputF)
page = pdf.get_page(1)
#signature image
imageobject = Origami::Graphics::ImageXObject.from_image_file('c:\rails_projects\RecibosOnline\app\assets\images\logo.jpg', 'jpg')
imageobject.Width = 200
imageobject.Height = 141
#formobject = Origami::Graphics::FormXObject.new
#formobject.write("Teste")
width = 300
height=141
x=201
y=186
signedby = "My Company"
location = "Portugal"#pdf.signature[pdf.signature.keys[5]]
contact = "mail@mail.com" #pdf.signature[pdf.signature.keys[6]]
reason = "Testing" #pdf.signature[pdf.signature.keys[7]]
date = Time.now
caption="Digitally Signed By: #{signedby}\nContact: #{contact}\nLocation: #{location}\nReason: #{reason}\nDate: #{date} "
#DSBlankstream= "% DSBLank"
questionMark = "% DSUnknown\n" +
"q\n" +
"1 G\n" +
"1 g\n" +
"0.1 0 0 0.1 9 0 cm\n" +
"0 J 0 j 4 M []0 d\n" +
"1 i \n" +
"0 g\n" +
"313 292 m\n" +
"313 404 325 453 432 529 c\n" +
"478 561 504 597 504 645 c\n" +
"504 736 440 760 391 760 c\n" +
"286 760 271 681 265 626 c\n" +
"265 625 l\n" +
"100 625 l\n" +
"100 828 253 898 381 898 c\n" +
"451 898 679 878 679 650 c\n" +
"679 555 628 499 538 435 c\n" +
"488 399 467 376 467 292 c\n" +
"313 292 l\n" +
"h\n" +
"308 214 170 -164 re\n" +
"f\n" +
"0.44 G\n" +
"1.2 w\n" +
"1 1 0.4 rg\n" +
"287 318 m\n" +
"287 430 299 479 406 555 c\n" +
"451 587 478 623 478 671 c\n" +
"478 762 414 786 365 786 c\n" +
"260 786 245 707 239 652 c\n" +
"239 651 l\n" +
"74 651 l\n" +
"74 854 227 924 355 924 c\n" +
"425 924 653 904 653 676 c\n" +
"653 581 602 525 512 461 c\n" +
"462 425 441 402 441 318 c\n" +
"287 318 l\n" +
"h\n" +
"282 240 170 -164 re\n" +
"B\n" +
"Q\n";
n0 = Annotation::AppearanceStream.new
n0.Type=Origami::Name.new("XObject")
n0.BBox = [ 0, 0, 100, 100 ]
n0.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n0.set_indirect(true)
n0.Resources = Resources.new
n0.Resources.ProcSet = [Origami::Name.new("PDF"),Origami::Name.new("Text"),Origami::Name.new("Text"),Origami::Name.new("ImageB"),Origami::Name.new("ImageC"),Origami::Name.new("ImageI")]
n0.draw_stream('% DSBlank')
#n0.write(Origami::Name.new("% DSBlank"))
n1 = Annotation::AppearanceStream.new
n1.Type=Origami::Name.new("XObject")
n1.BBox = [ 0, 0, 100, 100 ]
n1.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n1.set_indirect(true)
n1.Resources = Resources.new
n1.Resources.ProcSet = [Origami::Name.new("PDF"),Origami::Name.new("Text"),Origami::Name.new("Text"),Origami::Name.new("ImageB"),Origami::Name.new("ImageC"),Origami::Name.new("ImageI")]
n1.draw_stream('% DSBlank')
n3 = Annotation::AppearanceStream.new
n3.Type=Origami::Name.new("XObject")
n3.BBox = [ 0, 0, 100, 100 ]
n3.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n3.set_indirect(true)
n3.Resources = Resources.new
n3.Resources.ProcSet = [Origami::Name.new("PDF"),Origami::Name.new("Text"),Origami::Name.new("Text"),Origami::Name.new("ImageB"),Origami::Name.new("ImageC"),Origami::Name.new("ImageI")]
n3.draw_stream('% DSBlank')
n2 = Annotation::AppearanceStream.new
n2.Type = Origami::Name.new("XObject")
#n2.Subtype = Origami::Name.new("Form")
n2.Resources = Resources.new
n2.Resources.ProcSet = [Origami::Name.new("Text")]
n2.set_indirect(true)
n2.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n2.BBox = [ 0, 0, width, height ]
n2.write(caption,:x => 40, :y => height-35, :size => 15)
#n2.draw_stream("q 0 0 198 48 re W n BT /Helv 7.645 Tf 0 g 0 40.135 Td (Digitally ) Tj 28.889 0 Td (signed ) Tj 24.652 0 Td (by ) Tj10.198 0 Td (James ) Tj 24.641 0 Td (Pravetz ) Tj-88.38 -9.174 Td (DN: ) Tj 15.29 0 Td (cn=James ) Tj37.18 0 Td (Pravetz, ) Tj 30.165 0 Td (c=CA, ) Tj 23.156 0 Td0 -9.174 Td (Reason: ) Tj 30.599 0 Td (I ) Tj 4.248 0 Td(have ) Tj 18.702 0 Td (reviewed ) Tj 32.719 0 Td(this ) Tj 14.02 0 Td (document ) Tj -100.288 -9.174 Td(Date: ) Tj 20.397 0 Td (2006.06.08 ) Tj 40.386 0 Td(13:39:35 ) Tj 31.883 0 Td (-07'00') Tj ET Q")
##Sets the root dictionary element
frm = Annotation::AppearanceStream.new
frm.set_indirect(true)
#frm.Type = Origami::Name.new("XObject")
#frm.Subtype = Origami::Name.new("Form")
frm.Resources = Resources.new
frm.Resources.ProcSet = [Origami::Name.new("PDF")]
frm.Resources.add_xobject(Origami::Name.new("n0"), n0)
frm.Resources.add_xobject(Origami::Name.new("n1"), n1)
frm.Resources.add_xobject(Origami::Name.new("n2"), n2)
frm.Resources.add_xobject(Origami::Name.new("n3"), n3)
frm.Matrix = [ 1, 0, 0, 1, 0, 0 ]
frm.BBox = [ 0, 0, width, height ]
frm.draw_stream('q 1 0 0 1 0 0 cm /n0 Do Q')
frm.draw_stream('q 1 0 0 1 0 0 cm /n1 Do Q')
frm.draw_stream('q 1 0 0 1 0 0 cm /n2 Do Q')
frm.draw_stream('q 1 0 0 1 0 0 cm /n3 Do Q')
xo17 = Annotation::Widget::Signature.new
#xo17 = Annotation::Widget::Signature.new
xo17.Rect = Rectangle[ llx: x, lly: y, urx: x+width, ury: y+height ]
#xo17.Resources = Resources.new
#xo17.Resources.add_xobject(Origami::Name.new("FRM"), frm)
xo17.F = Annotation::Flags::PRINT #sets the print mode on
xo17.H = Annotation::Widget::Highlight::INVERT
streamN = Annotation::AppearanceStream.new #.setFilter(:FlateDecode)
streamN.set_indirect(true)
streamN.BBox = [ 0, 0, width, height ]
streamN.Resources = Resources.new
streamN.Resources.ProcSet = [Origami::Name.new("PDF")]
streamN.Resources.add_xobject(Origami::Name.new("FRM"), frm)
streamN.Subtype = nil
#cs = ContentStream.new('q 1 0 0 1 0 0 cm /FRM Do Q',streamN)
streamN.draw_stream('q 1 0 0 1 0 0 cm /FRM Do Q')
#streamN.draw_image(Origami::Name.new("FRM"),{x:x,y:y})
#streamN.write(caption,:x => 40, :y => height-35, :size => 15)
xo17.set_normal_appearance(streamN)
# page.add_xobject(Origami::Name.new("FRM"),frm)
# page.add_xobject(Origami::Name.new("n0"),n0)
# page.add_xobject(Origami::Name.new("n2"),n2)
page.add_annot(xo17)
# Sign the PDF with the specified keys
pdf.sign(cert, key,
:method => 'adbe.pkcs7.sha1',
:annotation => xo17,
:location => location,
:contact => contact,
:reason => reason
)
# Save the resulting file
pdf.save(outputF)
end
SignPdf("Sample.pdf")
需要“openssl”
开始
需要“折纸”
救援装载错误
ORIGAMIDIR=“C:\RailsInstaller\Ruby1.9.3\lib\ruby\gems\1.9.1\gems\origami-1.2.4\lib”
$:高度-35,:尺寸=>15)
xo17.设置正常外观(streamN)
#第页添加对象(Origami::Name.new(“FRM”),FRM)
#第页添加对象(Origami::Name.new(“n0”),n0)
#第页添加对象(Origami::Name.new(“n2”),n2)
第页添加注释(xo17)
#使用指定的密钥对PDF进行签名
pdf.签名(证书、钥匙、,
:method=>'adbe.pkcs7.sha1',
:annotation=>xo17,
:location=>location,
:contact=>contact,
:原因=>原因
)
#保存结果文件
pdf.save(outputF)
结束
SignPdf(“Sample.pdf”)
多么激烈的战斗
我想说:
最后,获胜者是那些站在战场中央的人。悲伤地环顾四周的战场,想知道为什么会这样。只有当他们知道如何阅读…那么这些事情就不会发生了。但与此同时,如果没有这种情况发生,他们也不会知道自己不知道如何正确地阅读。有时候,一个人只需要知道如何真正理解他反复阅读的内容 PPKapearances文件中包含了所有内容。我甚至没有按照他们推荐的词典结构去做我所期望的那样。 我只需要添加n1和n3层,流内容甚至可以是“%DS Blank”。您找到的问号字符串流是我从解决方案的
PdfSignatureAppearance.cs
文件中获取的。如果我使用一个Foxit阅读器,就会显示问号(即使签名有效)。对于Adobe来说,我使用它或DSBlank
都无所谓
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
def draw_signature(name, attr = {})
load! if @instructions.nil?
x, y = attr[:x], attr[:y]
@instructions << PDF::Instruction.new('q')
@instructions << PDF::Instruction.new('cm', 1, 0, 0, 1, x, y)
@instructions << PDF::Instruction.new('Do', name)
@instructions << PDF::Instruction.new('Q')
end
def SignPdf(inputF)
@inputfile = String.new(inputF)
outputF = @inputfile.insert(inputF.rindex("."),"_signed8")
certFile = "cert.pem"
rsakeyFile = "pk.pem"
passphrase = "mypass"
key4pem=File.read rsakeyFile
key = OpenSSL::PKey::RSA.new key4pem, passphrase
cert = OpenSSL::X509::Certificate.new(File.read certFile)
pdf = PDF.read(inputF)
page = pdf.get_page(1)
#signature image
imageobject = Origami::Graphics::ImageXObject.from_image_file('c:\rails_projects\RecibosOnline\app\assets\images\logo.jpg', 'jpg')
imageobject.Width = 200
imageobject.Height = 141
#formobject = Origami::Graphics::FormXObject.new
#formobject.write("Teste")
width = 300
height=141
x=201
y=186
signedby = "My Company"
location = "Portugal"#pdf.signature[pdf.signature.keys[5]]
contact = "mail@mail.com" #pdf.signature[pdf.signature.keys[6]]
reason = "Testing" #pdf.signature[pdf.signature.keys[7]]
date = Time.now
caption="Digitally Signed By: #{signedby}\nContact: #{contact}\nLocation: #{location}\nReason: #{reason}\nDate: #{date} "
#DSBlankstream= "% DSBLank"
questionMark = "% DSUnknown\n" +
"q\n" +
"1 G\n" +
"1 g\n" +
"0.1 0 0 0.1 9 0 cm\n" +
"0 J 0 j 4 M []0 d\n" +
"1 i \n" +
"0 g\n" +
"313 292 m\n" +
"313 404 325 453 432 529 c\n" +
"478 561 504 597 504 645 c\n" +
"504 736 440 760 391 760 c\n" +
"286 760 271 681 265 626 c\n" +
"265 625 l\n" +
"100 625 l\n" +
"100 828 253 898 381 898 c\n" +
"451 898 679 878 679 650 c\n" +
"679 555 628 499 538 435 c\n" +
"488 399 467 376 467 292 c\n" +
"313 292 l\n" +
"h\n" +
"308 214 170 -164 re\n" +
"f\n" +
"0.44 G\n" +
"1.2 w\n" +
"1 1 0.4 rg\n" +
"287 318 m\n" +
"287 430 299 479 406 555 c\n" +
"451 587 478 623 478 671 c\n" +
"478 762 414 786 365 786 c\n" +
"260 786 245 707 239 652 c\n" +
"239 651 l\n" +
"74 651 l\n" +
"74 854 227 924 355 924 c\n" +
"425 924 653 904 653 676 c\n" +
"653 581 602 525 512 461 c\n" +
"462 425 441 402 441 318 c\n" +
"287 318 l\n" +
"h\n" +
"282 240 170 -164 re\n" +
"B\n" +
"Q\n";
n0 = Annotation::AppearanceStream.new
n0.Type=Origami::Name.new("XObject")
n0.BBox = [ 0, 0, 100, 100 ]
n0.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n0.set_indirect(true)
n0.Resources = Resources.new
n0.Resources.ProcSet = [Origami::Name.new("PDF"),Origami::Name.new("Text"),Origami::Name.new("Text"),Origami::Name.new("ImageB"),Origami::Name.new("ImageC"),Origami::Name.new("ImageI")]
n0.draw_stream('% DSBlank')
#n0.write(Origami::Name.new("% DSBlank"))
n1 = Annotation::AppearanceStream.new
n1.Type=Origami::Name.new("XObject")
n1.BBox = [ 0, 0, 100, 100 ]
n1.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n1.set_indirect(true)
n1.Resources = Resources.new
n1.Resources.ProcSet = [Origami::Name.new("PDF"),Origami::Name.new("Text"),Origami::Name.new("Text"),Origami::Name.new("ImageB"),Origami::Name.new("ImageC"),Origami::Name.new("ImageI")]
n1.draw_stream('% DSBlank')
n3 = Annotation::AppearanceStream.new
n3.Type=Origami::Name.new("XObject")
n3.BBox = [ 0, 0, 100, 100 ]
n3.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n3.set_indirect(true)
n3.Resources = Resources.new
n3.Resources.ProcSet = [Origami::Name.new("PDF"),Origami::Name.new("Text"),Origami::Name.new("Text"),Origami::Name.new("ImageB"),Origami::Name.new("ImageC"),Origami::Name.new("ImageI")]
n3.draw_stream('% DSBlank')
n2 = Annotation::AppearanceStream.new
n2.Type = Origami::Name.new("XObject")
#n2.Subtype = Origami::Name.new("Form")
n2.Resources = Resources.new
n2.Resources.ProcSet = [Origami::Name.new("Text")]
n2.set_indirect(true)
n2.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n2.BBox = [ 0, 0, width, height ]
n2.write(caption,:x => 40, :y => height-35, :size => 15)
#n2.draw_stream("q 0 0 198 48 re W n BT /Helv 7.645 Tf 0 g 0 40.135 Td (Digitally ) Tj 28.889 0 Td (signed ) Tj 24.652 0 Td (by ) Tj10.198 0 Td (James ) Tj 24.641 0 Td (Pravetz ) Tj-88.38 -9.174 Td (DN: ) Tj 15.29 0 Td (cn=James ) Tj37.18 0 Td (Pravetz, ) Tj 30.165 0 Td (c=CA, ) Tj 23.156 0 Td0 -9.174 Td (Reason: ) Tj 30.599 0 Td (I ) Tj 4.248 0 Td(have ) Tj 18.702 0 Td (reviewed ) Tj 32.719 0 Td(this ) Tj 14.02 0 Td (document ) Tj -100.288 -9.174 Td(Date: ) Tj 20.397 0 Td (2006.06.08 ) Tj 40.386 0 Td(13:39:35 ) Tj 31.883 0 Td (-07'00') Tj ET Q")
##Sets the root dictionary element
frm = Annotation::AppearanceStream.new
frm.set_indirect(true)
#frm.Type = Origami::Name.new("XObject")
#frm.Subtype = Origami::Name.new("Form")
frm.Resources = Resources.new
frm.Resources.ProcSet = [Origami::Name.new("PDF")]
frm.Resources.add_xobject(Origami::Name.new("n0"), n0)
frm.Resources.add_xobject(Origami::Name.new("n1"), n1)
frm.Resources.add_xobject(Origami::Name.new("n2"), n2)
frm.Resources.add_xobject(Origami::Name.new("n3"), n3)
frm.Matrix = [ 1, 0, 0, 1, 0, 0 ]
frm.BBox = [ 0, 0, width, height ]
frm.draw_stream('q 1 0 0 1 0 0 cm /n0 Do Q')
frm.draw_stream('q 1 0 0 1 0 0 cm /n1 Do Q')
frm.draw_stream('q 1 0 0 1 0 0 cm /n2 Do Q')
frm.draw_stream('q 1 0 0 1 0 0 cm /n3 Do Q')
xo17 = Annotation::Widget::Signature.new
#xo17 = Annotation::Widget::Signature.new
xo17.Rect = Rectangle[ llx: x, lly: y, urx: x+width, ury: y+height ]
#xo17.Resources = Resources.new
#xo17.Resources.add_xobject(Origami::Name.new("FRM"), frm)
xo17.F = Annotation::Flags::PRINT #sets the print mode on
xo17.H = Annotation::Widget::Highlight::INVERT
streamN = Annotation::AppearanceStream.new #.setFilter(:FlateDecode)
streamN.set_indirect(true)
streamN.BBox = [ 0, 0, width, height ]
streamN.Resources = Resources.new
streamN.Resources.ProcSet = [Origami::Name.new("PDF")]
streamN.Resources.add_xobject(Origami::Name.new("FRM"), frm)
streamN.Subtype = nil
#cs = ContentStream.new('q 1 0 0 1 0 0 cm /FRM Do Q',streamN)
streamN.draw_stream('q 1 0 0 1 0 0 cm /FRM Do Q')
#streamN.draw_image(Origami::Name.new("FRM"),{x:x,y:y})
#streamN.write(caption,:x => 40, :y => height-35, :size => 15)
xo17.set_normal_appearance(streamN)
# page.add_xobject(Origami::Name.new("FRM"),frm)
# page.add_xobject(Origami::Name.new("n0"),n0)
# page.add_xobject(Origami::Name.new("n2"),n2)
page.add_annot(xo17)
# Sign the PDF with the specified keys
pdf.sign(cert, key,
:method => 'adbe.pkcs7.sha1',
:annotation => xo17,
:location => location,
:contact => contact,
:reason => reason
)
# Save the resulting file
pdf.save(outputF)
end
SignPdf("Sample.pdf")
需要“openssl”
开始
需要“折纸”
救援装载错误
ORIGAMIDIR=“C:\RailsInstaller\Ruby1.9.3\lib\ruby\gems\1.9.1\gems\origami-1.2.4\lib”
$:高度-35,:尺寸=>15)
xo17.设置正常外观(streamN)
#第页添加对象(Origami::Name.new(“FRM”),FRM)
#第页添加对象(Origami::Name.new(“n0”),n0)
#第页添加对象(Origami::Name.new(“n2”),n2)
第页添加注释(xo17)
#使用指定的密钥对PDF进行签名
pdf.签名(证书、钥匙、,
:method=>'adbe.pkcs7.sha1',
:annotation=>xo17,
:location=>location,
:contact=>contact,
:原因=>原因
)
#保存结果文件
pdf.save(outputF)
结束
SignPdf(“Sample.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
def draw_signature(name, attr = {})
load! if @instructions.nil?
x, y = attr[:x], attr[:y]
@instructions << PDF::Instruction.new('q')
@instructions << PDF::Instruction.new('cm', 1, 0, 0, 1, x, y)
@instructions << PDF::Instruction.new('Do', name)
@instructions << PDF::Instruction.new('Q')
end
def SignPdf(inputF)
@inputfile = String.new(inputF)
outputF = @inputfile.insert(inputF.rindex("."),"_signed8")
certFile = "cert.pem"
rsakeyFile = "pk.pem"
passphrase = "mypass"
key4pem=File.read rsakeyFile
key = OpenSSL::PKey::RSA.new key4pem, passphrase
cert = OpenSSL::X509::Certificate.new(File.read certFile)
pdf = PDF.read(inputF)
page = pdf.get_page(1)
#signature image
imageobject = Origami::Graphics::ImageXObject.from_image_file('c:\rails_projects\RecibosOnline\app\assets\images\logo.jpg', 'jpg')
imageobject.Width = 200
imageobject.Height = 141
#formobject = Origami::Graphics::FormXObject.new
#formobject.write("Teste")
width = 300
height=141
x=201
y=186
signedby = "My Company"
location = "Portugal"#pdf.signature[pdf.signature.keys[5]]
contact = "mail@mail.com" #pdf.signature[pdf.signature.keys[6]]
reason = "Testing" #pdf.signature[pdf.signature.keys[7]]
date = Time.now
caption="Digitally Signed By: #{signedby}\nContact: #{contact}\nLocation: #{location}\nReason: #{reason}\nDate: #{date} "
#DSBlankstream= "% DSBLank"
questionMark = "% DSUnknown\n" +
"q\n" +
"1 G\n" +
"1 g\n" +
"0.1 0 0 0.1 9 0 cm\n" +
"0 J 0 j 4 M []0 d\n" +
"1 i \n" +
"0 g\n" +
"313 292 m\n" +
"313 404 325 453 432 529 c\n" +
"478 561 504 597 504 645 c\n" +
"504 736 440 760 391 760 c\n" +
"286 760 271 681 265 626 c\n" +
"265 625 l\n" +
"100 625 l\n" +
"100 828 253 898 381 898 c\n" +
"451 898 679 878 679 650 c\n" +
"679 555 628 499 538 435 c\n" +
"488 399 467 376 467 292 c\n" +
"313 292 l\n" +
"h\n" +
"308 214 170 -164 re\n" +
"f\n" +
"0.44 G\n" +
"1.2 w\n" +
"1 1 0.4 rg\n" +
"287 318 m\n" +
"287 430 299 479 406 555 c\n" +
"451 587 478 623 478 671 c\n" +
"478 762 414 786 365 786 c\n" +
"260 786 245 707 239 652 c\n" +
"239 651 l\n" +
"74 651 l\n" +
"74 854 227 924 355 924 c\n" +
"425 924 653 904 653 676 c\n" +
"653 581 602 525 512 461 c\n" +
"462 425 441 402 441 318 c\n" +
"287 318 l\n" +
"h\n" +
"282 240 170 -164 re\n" +
"B\n" +
"Q\n";
n0 = Annotation::AppearanceStream.new
n0.Type=Origami::Name.new("XObject")
n0.BBox = [ 0, 0, 100, 100 ]
n0.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n0.set_indirect(true)
n0.Resources = Resources.new
n0.Resources.ProcSet = [Origami::Name.new("PDF"),Origami::Name.new("Text"),Origami::Name.new("Text"),Origami::Name.new("ImageB"),Origami::Name.new("ImageC"),Origami::Name.new("ImageI")]
n0.draw_stream('% DSBlank')
#n0.write(Origami::Name.new("% DSBlank"))
n1 = Annotation::AppearanceStream.new
n1.Type=Origami::Name.new("XObject")
n1.BBox = [ 0, 0, 100, 100 ]
n1.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n1.set_indirect(true)
n1.Resources = Resources.new
n1.Resources.ProcSet = [Origami::Name.new("PDF"),Origami::Name.new("Text"),Origami::Name.new("Text"),Origami::Name.new("ImageB"),Origami::Name.new("ImageC"),Origami::Name.new("ImageI")]
n1.draw_stream('% DSBlank')
n3 = Annotation::AppearanceStream.new
n3.Type=Origami::Name.new("XObject")
n3.BBox = [ 0, 0, 100, 100 ]
n3.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n3.set_indirect(true)
n3.Resources = Resources.new
n3.Resources.ProcSet = [Origami::Name.new("PDF"),Origami::Name.new("Text"),Origami::Name.new("Text"),Origami::Name.new("ImageB"),Origami::Name.new("ImageC"),Origami::Name.new("ImageI")]
n3.draw_stream('% DSBlank')
n2 = Annotation::AppearanceStream.new
n2.Type = Origami::Name.new("XObject")
#n2.Subtype = Origami::Name.new("Form")
n2.Resources = Resources.new
n2.Resources.ProcSet = [Origami::Name.new("Text")]
n2.set_indirect(true)
n2.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n2.BBox = [ 0, 0, width, height ]
n2.write(caption,:x => 40, :y => height-35, :size => 15)
#n2.draw_stream("q 0 0 198 48 re W n BT /Helv 7.645 Tf 0 g 0 40.135 Td (Digitally ) Tj 28.889 0 Td (signed ) Tj 24.652 0 Td (by ) Tj10.198 0 Td (James ) Tj 24.641 0 Td (Pravetz ) Tj-88.38 -9.174 Td (DN: ) Tj 15.29 0 Td (cn=James ) Tj37.18 0 Td (Pravetz, ) Tj 30.165 0 Td (c=CA, ) Tj 23.156 0 Td0 -9.174 Td (Reason: ) Tj 30.599 0 Td (I ) Tj 4.248 0 Td(have ) Tj 18.702 0 Td (reviewed ) Tj 32.719 0 Td(this ) Tj 14.02 0 Td (document ) Tj -100.288 -9.174 Td(Date: ) Tj 20.397 0 Td (2006.06.08 ) Tj 40.386 0 Td(13:39:35 ) Tj 31.883 0 Td (-07'00') Tj ET Q")
##Sets the root dictionary element
frm = Annotation::AppearanceStream.new
frm.set_indirect(true)
#frm.Type = Origami::Name.new("XObject")
#frm.Subtype = Origami::Name.new("Form")
frm.Resources = Resources.new
frm.Resources.ProcSet = [Origami::Name.new("PDF")]
frm.Resources.add_xobject(Origami::Name.new("n0"), n0)
frm.Resources.add_xobject(Origami::Name.new("n1"), n1)
frm.Resources.add_xobject(Origami::Name.new("n2"), n2)
frm.Resources.add_xobject(Origami::Name.new("n3"), n3)
frm.Matrix = [ 1, 0, 0, 1, 0, 0 ]
frm.BBox = [ 0, 0, width, height ]
frm.draw_stream('q 1 0 0 1 0 0 cm /n0 Do Q')
frm.draw_stream('q 1 0 0 1 0 0 cm /n1 Do Q')
frm.draw_stream('q 1 0 0 1 0 0 cm /n2 Do Q')
frm.draw_stream('q 1 0 0 1 0 0 cm /n3 Do Q')
xo17 = Annotation::Widget::Signature.new
#xo17 = Annotation::Widget::Signature.new
xo17.Rect = Rectangle[ llx: x, lly: y, urx: x+width, ury: y+height ]
#xo17.Resources = Resources.new
#xo17.Resources.add_xobject(Origami::Name.new("FRM"), frm)
xo17.F = Annotation::Flags::PRINT #sets the print mode on
xo17.H = Annotation::Widget::Highlight::INVERT
streamN = Annotation::AppearanceStream.new #.setFilter(:FlateDecode)
streamN.set_indirect(true)
streamN.BBox = [ 0, 0, width, height ]
streamN.Resources = Resources.new
streamN.Resources.ProcSet = [Origami::Name.new("PDF")]
streamN.Resources.add_xobject(Origami::Name.new("FRM"), frm)
streamN.Subtype = nil
#cs = ContentStream.new('q 1 0 0 1 0 0 cm /FRM Do Q',streamN)
streamN.draw_stream('q 1 0 0 1 0 0 cm /FRM Do Q')
#streamN.draw_image(Origami::Name.new("FRM"),{x:x,y:y})
#streamN.write(caption,:x => 40, :y => height-35, :size => 15)
xo17.set_normal_appearance(streamN)
# page.add_xobject(Origami::Name.new("FRM"),frm)
# page.add_xobject(Origami::Name.new("n0"),n0)
# page.add_xobject(Origami::Name.new("n2"),n2)
page.add_annot(xo17)
# Sign the PDF with the specified keys
pdf.sign(cert, key,
:method => 'adbe.pkcs7.sha1',
:annotation => xo17,
:location => location,
:contact => contact,
:reason => reason
)
# Save the resulting file
pdf.save(outputF)
end
SignPdf("Sample.pdf")