How to Obtain the Digital Signature From a Signed PDF Document?

428 views
Skip to first unread message

Vincent Ycasas

unread,
Nov 22, 2013, 1:56:31 PM11/22/13
to pdfne...@googlegroups.com
Question:
How can I extract the digital signature from a PDF that has been already signed?

Answer:
To obtain the certificate, you will need to locate the signature form field and get its value. For example:
PDFDoc doc = ...
if (doc.HasSignatures()) {
   
Field sigField = doc.GetField("My SignatureField's Name"); // you will need to know the name of the signature field.
   
Obj value = sigField.GetValue();
   
// value is the signature dictionary and has the following:
   
//   1. Type
   
//   2. Filter
   
//   3. ByteRange
   
//   4. Contents
   
// The Contents entry in the signature dictionary will contain the signature envelope which will hold the public certificate which can be used to verify the signature.
}

Ryan

unread,
Sep 26, 2016, 2:24:31 PM9/26/16
to pdfne...@googlegroups.com
Question:

How do I get the date, location, name, etc. of the signature?

Answer:

While the digital signature certificate defined in the Contents entry, mentioned above, may contain this information, the PDF can also.

The following code will iterate all the digital signatures in a PDFDoc object, and print out the string metadata for that signature. The switch statement also includes the other possible entries, though these other ones are non-text. See PDF32000_2008 PDF 1.7, Section 12.8.1 Digital Signatures General, Table 252 "Entries in a signature dictionary" for details of these other entries.

if(!doc.hasSignatures()) return;

FieldIterator fitr = doc.getFieldIterator();
while(fitr.hasNext())
{
   
Field field=(Field)(fitr.next());
   
int type = field.getType();
   
if(type != Field.e_signature) continue;
   
Obj value = field.getValue();
   
if(value == null || !value.isDict()) continue;

   
System.out.println("========================================");
   
System.out.println(field.getName());
   
for (DictIterator itr = value.getDictIterator(); itr.hasNext(); itr.next())
   
{
       
String k = itr.key().getName();
       
switch(k)
       
{
           
// case "Filter":
           
// case "SubFilter":
           
// case "Contents":
           
// case "Cert":
           
// case "Reference":
           
case "ByteRange":
               
for (int i = 0; i < itr.Value().Size(); i += 2 )
               
{
                   
int offset = (int)itr.value().getAt(i).getNumber();
                   
int length_in_bytes = (int)itr.value().getAt(i + 1).getNumber();
                   
System.out.println("ByteRange " + offset + "-" + (offset + length_in_bytes - 1));
               
}
               
break;
           
case "Changes":
               
Obj v = itr.value();
               
if(v.isArray() && v.size() == 3)
               
{
                   
int num_pages_altered = (int)v.getAt(0).getNumber();
                   
int num_fields_altered = (int)v.getAt(1).getNumber();
                   
int num_fields_filled = (int)v.getAt(2).getNumber();
                   
System.out.println(num_pages_altered + " Pages Altered\n" + num_fields_altered + " Fields Altered\n" + num_fields_filled + " Fields Filled in");
               
}
               
break;
           
case "Name":
           
case "M":
           
case "Location":
           
case "Reason":
           
case "ContectInfo":
               
System.out.println(k + " : " + itr.value().getAsPDFText());
               
break;
           
case "R":
           
case "V":
               
System.out.println(k + " : " + itr.value().getNumber());
               
break;
           
// case "Prop_Build":
           
// case "Prop_AuthTime":
           
// case "Prop_AuthType":
       
}
   
}
   
System.out.println("========================================");
}



Reply all
Reply to author
Forward
0 new messages