Skip to content

Instantly share code, notes, and snippets.

@martintsch
Forked from matiaskorhonen/sign-pdf.rb
Created June 5, 2018 10:35
Show Gist options
  • Save martintsch/d341ccd9b08aa5b2ba2a6faf79bd22d2 to your computer and use it in GitHub Desktop.
Save martintsch/d341ccd9b08aa5b2ba2a6faf79bd22d2 to your computer and use it in GitHub Desktop.

Revisions

  1. @matiaskorhonen matiaskorhonen revised this gist Mar 2, 2016. 1 changed file with 24 additions and 5 deletions.
    29 changes: 24 additions & 5 deletions sign-pdf.rb
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,7 @@
    #!/usr/bin/env ruby

    require "openssl"
    require "time"

    begin
    require "origami"
    @@ -9,7 +10,6 @@
    end
    include Origami

    # openssl req -x509 -newkey rsa:2048 -keyout private_key.pem -out certificate.crt -days 3650 -nodes
    CERT_FILE = "certificate.crt"
    KEY_FILE = "private_key.pem"

    @@ -28,16 +28,35 @@
    pdf = PDF.read(file)
    page = pdf.get_page(1)

    width = 200.0
    height = 50.0
    x = page.MediaBox[2].to_f - width - height
    y = height
    size = 8

    now = Time.now

    text_annotation = Annotation::AppearanceStream.new
    text_annotation.Type = Origami::Name.new("XObject")
    text_annotation.Resources = Resources.new
    text_annotation.Resources.ProcSet = [Origami::Name.new("Text")]
    text_annotation.set_indirect(true)
    text_annotation.Matrix = [ 1, 0, 0, 1, 0, 0 ]
    text_annotation.BBox = [ 0, 0, width, height ]
    text_annotation.write("Signed at #{now.iso8601}", x: size, y: (height/2)-(size/2), size: size)

    # 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]
    signature_annotation = Annotation::Widget::Signature.new
    signature_annotation.Rect = Rectangle[llx: x, lly: y+height, urx: x+width, ury: y]
    signature_annotation.F = Annotation::Flags::PRINT
    signature_annotation.set_normal_appearance(text_annotation)

    page.add_annot(sigannot)
    page.add_annot(signature_annotation)

    # Sign the PDF with the specified keys
    pdf.sign(cert, key,
    method: "adbe.pkcs7.sha1",
    annotation: sigannot,
    annotation: signature_annotation,
    location: "Helsinki",
    contact: "[email protected]",
    reason: "Proof of Concept"
  2. @matiaskorhonen matiaskorhonen revised this gist Feb 29, 2016. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions sign-pdf.rb
    Original file line number Diff line number Diff line change
    @@ -9,6 +9,7 @@
    end
    include Origami

    # openssl req -x509 -newkey rsa:2048 -keyout private_key.pem -out certificate.crt -days 3650 -nodes
    CERT_FILE = "certificate.crt"
    KEY_FILE = "private_key.pem"

  3. @matiaskorhonen matiaskorhonen created this gist Feb 29, 2016.
    47 changes: 47 additions & 0 deletions sign-pdf.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    #!/usr/bin/env ruby

    require "openssl"

    begin
    require "origami"
    rescue LoadError
    abort "origami not installed: gem install origami"
    end
    include Origami

    CERT_FILE = "certificate.crt"
    KEY_FILE = "private_key.pem"

    input_files = ARGV

    if input_files.empty?
    abort "Usage: sign-pdf input.pdf [...]"
    end

    key = OpenSSL::PKey::RSA.new(File.read(KEY_FILE))
    cert = OpenSSL::X509::Certificate.new(File.read(CERT_FILE))

    input_files.each do |file|
    output_filename = file.dup.insert(file.rindex("."), "_signed")

    pdf = PDF.read(file)
    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: "Helsinki",
    contact: "[email protected]",
    reason: "Proof of Concept"
    )

    # Save the resulting file
    pdf.save(output_filename)
    end