Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何使pdf签名可见(以及有效性图标)_Ruby_Pdf_Digital Signature_Visible - Fatal编程技术网

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

最初的问题是如何使用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"
  $: << 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")