Click here to Skip to main content
Click here to Skip to main content

iSafePDF: The Open Source PDF Signature Tool

By , 3 Jun 2010
 

iSafePDF.png

Introduction

Four years ago, I wrote an article about signing a PDF document using the iTextSharp library. I was surprised by the number of comments and emails I received about it.

Many people asked me for new features and ideas, I didn't have enough time to answer them all for two reasons:

  1. I had not enough spare time to implement the new features
  2. I was not able to implement some features they asked for because of the lack of iTextSharp documentation, and some bugs/lacks in older versions.

Now iTextSharp v5.x is out and comes with many new features. This article will only cover the digital signature, encryption, and meta-data manipulation parts. iTextSharp is more than this, it allows you to create and manipulate PDF without using any proprietary library!

I developed iSafePDF for my own needs and tried to implement features that many people asked for: loading certificates from a local user store, time-stamped signature, and PDF encryption (only password encryption is supported right now).

Getting started

You can read my first article about digital signature "E-signing PDF documents with iTextSharp". It describes an old and simple code (the base code of iSafePDF) which is easier to understand.

What you have to know, is that PDF digital signature and encryption provided by iTextSharp library are all PDF standards. this mean that any PDF viewer will be able to read encrypted document (if you provide the encryption password) and check signature without the need to install 3rd party plugin or so.

Using the binary

This article comes with the iSafePDF binary. No setup is needed, all you have to do is to uncompress the zip file and put the exe program somewhere in your disk and then run it.

The document tab

isafepdf-main.jpg

In this tab, you have to choose at least:

  1. The source file: this is the document you want to sign, the document itself will not be modified.
  2. The target file: this document will be a copy of the source document to which the signature and encryption will be applied.

If you want, you can modify the document meta-data.

The signature tab

isafepdf-signature.jpg

This tab allows you to control the digital signature. If you have locally installed certificates you will see them in the Certificates list. You also have the choice to sign your document using a pfx file if certificates are exported to pfx format (see my first article for more information).

PDF Signature standard allows you to add three fields to the digital signature: the reason, the contact, and the location they are visible when you visualize the digital signature information.

If you want, you can make the signature visible in the document; in this case, it will be put on the first page in the lower left corner (in the next release, I'll add more options to configure visible signatures: position, custom image ...etc).

The PDF standard allows you to use a time stamp authority (TSA); using this feature will make your document signature valid even if the digital signature certificate expires, as the TSA will prove that the certificate was valid when the document was signed.

Notes

Encryption tab

isafepdf-encryption.jpg

Here, you can choose to activate or not the document encryption; if encryption is active, you need to enter two passwords. The user password allows you to open and read the document, plus do what encryption allows you to do. The owner password allows you to modify encryption options using iSagePDF or another PDF manipulation program. It also allows you to open and read the document.

The source code

You can get the latest source code version from the iSagePDF official site: http://isafepdf.eurekaa.org/.

The most important method in the code is the Sign method. Please refer to my first article ("E-signing PDF documents with iTextSharp") to read the description of a simpler Sign method version (without encryption and timestamp).

The old Sign method used a WINCER_SIGNED signature type. This method is easier to implement because iTextSharp does all the signature jobs, but this option doesn't allow TSA support. To support TSA, we need to use the SELF_SIGNED signature type. Using this option gives us more control on the signature process, but then we need to calculate the signature digest. Below is a piece of code from the new Sign() method implementing the self signed document signature type:

//
sap.SetCrypto(null, this.myCert.Chain, null, PdfSignatureAppearance.SELF_SIGNED); 
// here we choose the self signed type

...

PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, 
                       new PdfName("adbe.pkcs7.detached")); 
// we will sign the document using a detached pkcs7
// certificate (generated from the pfx certificate).

...


//Bellow we calculate the SHA1 digest - this code
//is taken from iTextSharp tutorials
PdfPKCS7 sgn = new PdfPKCS7(this.myCert.Akp, 
               this.myCert.Chain, null, "SHA1", false);
IDigest messageDigest = DigestUtilities.GetDigest("SHA1");
Stream data = sap.RangeStream;
byte[] buf = new byte[8192];
int n;
while ((n = data.Read(buf, 0, buf.Length)) > 0)
{
    messageDigest.BlockUpdate(buf, 0, n);
}
byte[] hash = new byte[messageDigest.GetDigestSize()];
messageDigest.DoFinal(hash, 0);


DateTime cal = DateTime.Now;
byte[] ocsp = null;
if (this.myCert.Chain.Length >= 2)
{
    String url = PdfPKCS7.GetOCSPURL(this.myCert.Chain[0]);
    if (url != null && url.Length > 0)
        ocsp = new OcspClientBouncyCastle(this.myCert.Chain[0], 
                   this.myCert.Chain[1], url).GetEncoded();
}
byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, cal, ocsp);

sgn.Update(sh, 0, sh.Length);
//

The piece of code to add TSA is:

byte[] encodedSigTsa = sgn.GetEncodedPKCS7(hash, cal, this.myCert.Tsc, ocsp);
System.Array.Copy(encodedSigTsa, 0, paddedSig, 0, encodedSigTsa.Length);

//this.myCert.Tsc is of type TSAClientBouncyCastle and build from a TSA url,
//TSA login and TSA password. See Cert.cs for detailed information.

To support PDF encryption, I added a new class called PDFEncryption (see PDFEncryption.cs).

I will enumerate all the PDF encryption types:

public enum permissionType    { 
    Assembly = PdfWriter.ALLOW_ASSEMBLY,
    Copy = PdfWriter.ALLOW_COPY,
    DegradedPrinting = PdfWriter.ALLOW_DEGRADED_PRINTING,
    FillIn = PdfWriter.ALLOW_FILL_IN,
    ModifyAnnotation = PdfWriter.ALLOW_MODIFY_ANNOTATIONS,
    ModifyContent = PdfWriter.ALLOW_MODIFY_CONTENTS,
    Printing = PdfWriter.ALLOW_PRINTING,
    ScreenReaders = PdfWriter.ALLOW_SCREENREADERS };

The encryption method using a permission list is quite simple with iTextSharp (we use the PDFStamper).

public List<permissionType> Permissions = new List<permissionType>();

...

public void Encrypt(PdfStamper stamper)
{
   int permission = 0;
   foreach (int i in this.Permissions)
   {
       permission |= (int)i;
   }
   stamper.SetEncryption(this.Encryption, this.UserPwd, this.OwnerPwd, permission);
}

The future of iSafePDF

I'm planning to make iSafePDF as complete as possible with new features related to PDF security and encryption. The next release will add more configuration options to visual signature: choose custom signature position, and use a custom image (a scanned signature, for example).

I'll also add a console version, and an API to make batch processing easier, in a future release.

To get the latest binaries/source code of iSafePDF, please visit the official website: http://isafepdf.eurekaa.org/.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

About the Author

Alaa-eddine KADDOURI
Software Developer
France France
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionLicence for commercial product (close source)membermajco3339 Mar '13 - 22:28 
AnswerRe: Licence for commercial product (close source)memberAlaa-eddine KADDOURI10 Mar '13 - 1:58 
GeneralRe: Licence for commercial product (close source)memberAlaa-eddine KADDOURI10 Mar '13 - 2:06 
GeneralRe: Licence for commercial product (close source)membermajco33310 Mar '13 - 5:29 
QuestionVote of 5memberKalpana Volety11 Jan '13 - 11:42 
AnswerRe: Vote of 5memberAlaa-eddine KADDOURI11 Jan '13 - 12:13 
GeneralRe: Vote of 5memberKalpana Volety11 Jan '13 - 22:22 
QuestionWhat type of Encryption is Used?membersp08179 Nov '12 - 22:09 
GeneralMy vote of 5memberKuthuparakkal15 Oct '12 - 17:12 
QuestionWhich certificate to use?memberoscargs22 May '12 - 4:57 
AnswerRe: Which certificate to use?memberAlaa-eddine KADDOURI22 May '12 - 22:06 
GeneralRe: Which certificate to use?memberoscargs24 May '12 - 3:16 
Questiondoes not work with smart cardmemberTirad26 Feb '12 - 22:35 
AnswerRe: does not work with smart cardmemberAlaa-eddine KADDOURI26 Feb '12 - 23:09 
QuestionIt does not work with window certificate store !membertucminhqua3 Jan '12 - 19:54 
AnswerRe: It does not work with window certificate store !memberAlaa-eddine KADDOURI3 Jan '12 - 21:31 
GeneralRe: It does not work with window certificate store !membertucminhqua4 Jan '12 - 1:48 
GeneralRe: It does not work with window certificate store !memberAlaa-eddine KADDOURI26 Feb '12 - 23:11 
GeneralRe: It does not work with window certificate store !membertucminhqua1 Mar '12 - 4:23 
BugError: iSafePDF v1.3.0 Source Code and iSafePDF v1.3.0 binarymembertucminhqua2 Jan '12 - 5:42 
GeneralRe: Error: iSafePDF v1.3.0 Source Code and iSafePDF v1.3.0 binarymemberAlaa-eddine KADDOURI3 Jan '12 - 21:29 
GeneralRe: Error: iSafePDF v1.3.0 Source Code and iSafePDF v1.3.0 binarymemberMember 598433912 Jan '12 - 3:57 
QuestionCertificate encryptionmemberHooonza18 Oct '11 - 23:55 
QuestionCoolmemberReza Samadabadi3 Jul '11 - 23:16 
GeneralMy vote of 5membershreelimbkar28 Apr '11 - 19:03 
GeneralMy vote of 5memberMauro Gagna18 Apr '11 - 3:32 
QuestionExcellent jobmemberla_morte5 Feb '11 - 7:08 
AnswerRe: Excellent jobmemberAlaa-eddine KADDOURI5 Feb '11 - 8:19 
GeneralRe: Excellent jobmemberla_morte6 Feb '11 - 5:03 
GeneralThanks for this excellent articlemembermpino31 Jan '11 - 22:52 
GeneralRe: Thanks for this excellent articlememberAlaa-eddine KADDOURI31 Jan '11 - 23:22 
Generalsign/encrypt with public key, instead of private keymembertanimulbari20 Dec '10 - 1:48 
GeneralRe: sign/encrypt with public key, instead of private keymemberAlaa-eddine KADDOURI20 Dec '10 - 3:55 
GeneralRe: sign/encrypt with public key, instead of private keymembertanimulbari20 Dec '10 - 4:06 
GeneralRe: sign/encrypt with public key, instead of private keymemberAlaa-eddine KADDOURI20 Dec '10 - 4:22 
GeneraliSafePDF v1.3.0 is outmemberAlaa-eddine KADDOURI3 Sep '10 - 2:45 
GeneralRe: iSafePDF v1.3.0 is outmemberRubyPdf27 Sep '10 - 21:21 
GeneralRe: iSafePDF v1.3.0 is outmemberAlaa-eddine KADDOURI27 Sep '10 - 23:00 
GeneralSmart cardsmemberpandolf22 Jul '10 - 11:44 
GeneralRe: Smart cardsmemberluisvilc2612 Aug '10 - 16:35 
AnswerRe: Smart cardsmemberMember 367484111 Feb '12 - 8:18 
GeneralNice articlememberkadaoui el mehdi4 Jun '10 - 13:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130513.1 | Last Updated 3 Jun 2010
Article Copyright 2010 by Alaa-eddine KADDOURI
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid