gettalong / hexapdf

Versatile PDF creation and manipulation for Ruby
https://hexapdf.gettalong.org
Other
1.21k stars 69 forks source link

Remove digital certificate #290

Closed WSPDV closed 6 months ago

WSPDV commented 6 months ago

Hai mas @gettalong ~ i have a question about how to remove the digital cert without breaking the document?

i already tried some scripts but the document is corrupted.

  1. remove the sigflags
@doc = HexaPDF::Document.open(path)
@output_file = "tmp/HILANG-#{Time.now.to_i}.pdf"

if @doc.trailer[:Root] && @doc.trailer[:Root][:AcroForm] && @doc.trailer[:Root][:AcroForm][:SigFlags]
  @doc.trailer[:Root][:AcroForm].delete(:SigFlags)
end

@doc.write(@output_file)

the result is image's digital signature still exists then there is an error message like the picture below

image
  1. copy page per page
@doc = HexaPDF::Document.open(path)
@output_file = "tmp/HILANG-#{Time.now.to_i}.pdf"

new_pdf = HexaPDF::Document.new
@doc.pages.each { |page| new_pdf.pages << new_pdf.import(page) }

new_pdf.task(:optimize, compact: true, object_streams: :generate,
                        compress_pages: false)
new_pdf.write(@output_file)

the result is the same

any suggestion for removing certiface, mas?

gettalong commented 6 months ago

The following should do the trick:

require 'hexapdf'

HexaPDF::Document.open(ARGV[0]) do |doc|
  doc.acro_form.each_field do |field|
    next unless field.field_type == :Sig
    doc.delete(field.field_value)
    doc.delete(field)
  end
  doc.acro_form.find_root_fields!
  doc.acro_form.signature_unflag(:signatures_exist, :append_only)
  doc.write('/tmp/nosig.pdf', optimize: true)
end
WSPDV commented 6 months ago

is it expected there is information on the deleted signature, mas @gettalong ?

image

and in the signature panel will show the details below

image

can we remove the image signature and detail certification (not shown on the signature panel)?

WSPDV commented 6 months ago

hai mas @gettalong

I try to combine your code with my code like below

require 'hexapdf'

doc = HexaPDF::Document.open(path)
output_file = "tmp/HILANG-#{Time.now.to_i}.pdf"

doc.acro_form.each_field do |field|
    next unless field.field_type == :Sig

    doc.delete(field.field_value)
    doc.delete(field)
end

doc.acro_form.find_root_fields!
doc.acro_form.signature_unflag(:signatures_exist, :append_only)
doc.pages.each do |page|
page.delete(:Annots)
end
doc.write(@output_file, optimize: true)

the certificate is removed and the annotation does not appear

thank you mas @gettalong

gettalong commented 6 months ago

@WSPDV Ah, thanks for the response. My code was missing the deletion of the annotations that were not embedded in the field itself. So one would need to add field.each_widget {|widget| field.delete_widget(widget) } before deleting the field itself.

I will add a field deletion method to the main form dictionary to make this use-case easier.