Persits Software, Inc. Web Site
 Navigator:  Home |  Manual |  Chapter 8: Security
Chapter 9: Working with Existing PDFs Chapter 7: Tables
  Chapter 8: Security
8.1 Overview of PDF Security
8.2 PdfDocument.Encrypt Method
8.3 Digital Signing

8.1 Overview of PDF Security

A secure PDF is a document that imposes a set of restrictions on this document’s user, such as requiring a password on opening, or preventing copying/pasting of the document’s content.

There are two aspects to the standard (or built-in) PDF security: password protection and permission flags.

8.1.1 Password Protection

When a secure PDF is created, the document author supplies two secret strings: the Owner and User passwords. Applying these two passwords to the document using an algorithm described in Adobe PDF specifications produces a secure document.

A secure PDF’s content is encrypted with the RC4 algorithm, a stream cipher invented by Ron Rivest of RSA Security. Either a 40-bit or 128-bit key can be used. An encryption key is derived from the user password alone. The owner password is used to encrypt the user password and also to protect the immutability of the document’s permission flags. An encrypted copy of the user password is embedded in a secure PDF for validation purposes.

To open an encrypted document, the viewer must specify either the user or owner password. Specifying the valid user password enables a user to view the document, but also makes her subject to the permission flags associated with the document. For example, a user may not be able to modify or print the document. Specifying the valid owner password gives the user full control over the document: not only can she view it, but also change or remove its security settings.

An empty string is a perfectly valid value for either password. There are 4 possible password use scenarios:

Scenario 1: Both user and owner passwords are non-empty and not equal to each other.

A user must specify a password to open the document. Use this scenario to create private password-protected documents with certain usage restrictions imposed, such as "no printing". If the two passwords are the same, the owner password is ignored and this turns into Scenario 3.
Scenario 2: The owner password is non-empty, the user password is empty.
The document can be viewed without specifying a password, but a user is subject to permission flags. Use this scenario to create publicly accessible documents with certain usage restrictions imposed.
Scenario 3: The owner password is empty, the user password is non-empty.
A user must specify a password to open the document. Use this scenario to create password-protected documents with no usage restrictions.
Scenario 4: Both the owner and user passwords are empty.
Although technically the document is encrypted, there is no true security in it as anyone can read the document and modify/remove permission flags. Using this scenario is not recommended.

8.1.2 Permission Flags

Version 4.0 and earlier of the Adobe Acrobat family of products supported 40-bit encryption, and recognized the following four permission flags:

This version of security specifications is referred to as Revision 2.

Adobe Acrobat 5.0 and higher allowed both 40-bit and 128-bit encryption, and introduced a more granular permission system. The new version of security specifications is referred to as Revision 3. The following permission flags are used in Revision 3:

  • Bit 3: Print the document, possibly not at high-resolution depending on Bit 12;
  • Bit 4: Modify content of the document by operations other than those controlled by Bits 6,9, and 11;
  • Bit 5: Copy/ extract content by operations other than those controlled by Bit 10;
  • Bit 6: Add and change annotations, fill in form fields, and if Bit 4 is also set, create or modify interactive form fields;
  • Bit 9: Fill in existing interactive form fields, even if Bit 6 is clear;
  • Bit 10: Extract text and graphics (in support of accessibility to disabled users)
  • Bit 11: Assemble the document (insert, rotate, or delete pages, and create bookmarks or thumbnail images), even if Bit 4 is clear.
  • Bit 12: Print the document to a representation from which a faithful digital copy of the PDF content could be generated. When this bit is clear (and Bit 3 is set) printing is limited to a low-level representation of the appearance.
8.2 PdfDocument.Encrypt Method
To make a PDF document secure with AspPDF, all you have to do is call the Encrypt method of the PdfDocument object. This method accepts 4 arguments, all optional: the owner password, user password, key length, and permission flags.

The owner and user password arguments are empty strings by default. To avoid Scenario 4 described above, you should set at least one of the passwords, or both, to non-empty strings. Specifying identical strings for both passwords will result in the owner password being ignored.

The key length argument must be set to either 40 or 128. The default value is 40.

The permission flags argument should be set to a bit-wise combination of the permission flag constants defined by the AspPDF components. These constants are:

pdfFull = &HFFFFFFFC (all significant bits)
pdfPrint = &H04 (Bit 3)
pdfModify = &H08 (Bit 4)
pdfCopy = &H10 (Bit 5)
pdfAnnotations = &H20 (Bit 6)
pdfForm = &H0100 (Bit 9)
pdfExtract = &H0200 (Bit 10)
pdfAssemble = &H0400 (Bit 11)
pdfPrintHigh = &H0800 (Bit 12)

The default value for the permission flags argument is pdfFull.

To use the permission flag constants in VBScript, you must include a METADATA tag in your .asp file referencing the AspPDF type library (outside the <% and %> brackets). In C#, the type name pdfPermissions has to be put in front of the constant names.

VBScript
<!--METADATA TYPE="TypeLib" UUID="{414FEE4B-2879-4090-957E-423567FFCFC6}"-->

<%
...
Doc.Encrypt "abc", "xyz", 128, pdfFull And (Not pdfModify)
...
%>

C#
...
objDoc.Encrypt( "abc", "xyz", 128, pdfPermissions.pdfFull && (~pdfPermissions.pdfModify) );
...

The code sample 08_encrypt.asp/.aspx (not shown here) is almost identical to the Hello World sample used in Chapter 3, except that it also calls the Encrypt method. The string "abc" is used for the owner password, "xyz" for the user password, 128 for key length and no-printing/no-changing for the permission flags.

Click the links below to run this code sample:

http://localhost/asppdf/manual_08/08_encrypt.asp
http://localhost/asppdf/manual_08/08_encrypt.aspx  Why is this link not working?

You will be prompted to enter a password when opening this document in Acrobat Reader. You can either enter abc or xyz. The Reader will display a yellow key icon in the status bar indicating that the document is secure:

If you click on the key icon and select Document Security..., the Document Security dialog box comes up confirming the correct security properties of the document:

8.3 Digital Signing
A digital signature protects a document's integrity and provides proof of the signer's identity. AspPDF is capable of adding a X.509 certificate-based digital signature to a PDF document in PKCS#7 format via the Sign method of the PdfDocument object.

8.3.1 AspEncrypt

To create a digitally signed document, or sign an existing PDF, AspPDF has to be used in tandem with another Persits Software component, AspEncrypt. A free 30-day evaluation version of this component can be downloaded from the AspEncrypt.com web site.

AspEncrypt is a comprehensive cryptographic engine which, among other things, offers PKCS#7 digital signing functionality and provides programmable access to X.509 certificates. Using AspEncrypt, a signer certificate can be retrieved from a certificate store or .PFX file (also known as a PKCS#12 file). Click here for more information about AspEncrypt's certificate management functionality.

IMPORTANT: You must use Version 2.2.0.2 or higher of AspEncrypt to produce signed PDF documents. If you are currently running an older version, download your free upgrade here.

8.3.2 Sign Method

The Sign method expects an initialized instance of CryptoMessage, an AspEncrypt object responsible for PKCS#7 digital signing. The CryptoMessage object must be associated with an instance of CryptoCert, another AspEncrypt object representing a signer certificate. CryptoCert objects are obtainable from certificate stores (represented by the CryptoStore object).

The Sign method also accepts the signer name, reason for signing, and location arguments (the first one is required, the other two are optional), and also an optional parameter string or parameter object controlling the visibility and location of the signature field within the document.

The following code sample adds a signature to a PDF document based on a certificate in .pfx (PKCS#12) format:

...
Set CM = Server.CreateObject("Persits.CryptoManager")
Set Context = CM.OpenContext("", False)
Set Msg = Context.CreateMessage
CM.RevertToSelf
' to avoid a run-time error

Set Store = CM.OpenStoreFromPFX("c:\mycert.pfx", "mypassword")
Set Cert = Store.Certificates(1)
Msg.SetSignerCert Cert

Doc.Sign Msg, "John Smith", "I created this document.", "New York, NY"
...

If a signer certificate is located in a system certificate store (as opposed to .pfx), the code fragment responsible for obtaining a CryptoCert object would look as follows:

...
Set Store = CM.OpenStore("MY", True)
' or False
Set Cert = Store.Certificates("112B 0783 8D43 0887 4EDF 015B CF4E E109")
...

This fragment opens the "MY" store (containing personal certificates) located in the HKEY_LOCAL_MACHINE section of the registry (HKEY_CURRENT_USER would be used if False were passed to OpenStore), and obtains a certificate from the store by its serial number.

Obtaining a certificate from a PFX file is conceptually simpler, but is associated with some technical problems. The method OpenStoreFromPFX uses an undocumented CryptoAPI function PFXImportCertStore from the library Crypt32.dll. For this method to work under IIS 5.0/6.0, you must call CM.RevertToSelf prior to calling OpenStoreFromPFX, and your virtual directory's Application Protection option must be set to Low. Otherwise you will receive the error

Persits.CryptoManager.1 (0x800A0064)
The system cannot find the file specified.

In ASP.NET, the method CM.RevertToSelf does not seem to have any effect, and you must instead use CM.LogonUser with an Admin username and password.

The code sample 08_sign.asp (not shown here) is yet another version of our Hello World application. It generates documents that are both encrypted and digitally signed. Before running this code sample, make sure AspEncrypt (the latest version) is installed, and the virtual directory /AspPDF has the Application Protection option set to low.

It is recommended that Acrobat Reader 6.0+ be used to view digitally signed documents. Acrobat 5.0 (the full version, not the Reader) is also acceptable, but you must also download and install the VeriSign Document Signer plug-in, and only signatures based on VeriSign certificates seem to be recognized as valid by this plug-in. A free 60-day VeriSign certificate can be obtained here.

Click the link below to run this code sample:

http://localhost/asppdf/manual_08/08_sign.asp  Why is this link not working?

NOTE: A digitally signed document can only be saved to disk (via the Save method). Saving to memory or an HTTP stream cannot be used once Sign is called, and an attempt to call SaveToMemory or SaveHttp will result in an error exception.

8.3.3 Visible Signatures

By default, the Sign method creates an invisible signature. Using the last optional argument of the Sign method, it is possible to specify a page and location within that page where the signature icon is to appear.

The following code fragment draws a signature icon in the upper-left corner of the first page of the document (middle arguments omitted for brevity):

Doc.Sign Msg, ..., "visible=true;x=10,y=750;width=20;height=20;pageindex=1"

It is also possible to change the default appearance of a signature by drawing on the canvas of a PdfAnnot object returned by the Sign method. Annotations are described in detail in Chapter 10.

8.3.4 Signature Validation

AspPDF's digital signature functionality would not be complete without a way to verify an existing signature in a document.

Signature verification is implemented via the VerifySignature method of the PdfDocument object. VerifySignature can only be called on an instance of PdfDocument created via OpenDocument (the latter is described in detail in Chapter 9.) VerifySignature expects an empty CryptoMessage object as an argument.

VerifySignature returns Nothing if no PKCS#7 signatures are found in the document. Otherwise, it returns an instance of the PdfSignature object encapsulating various property of the signature, including its validation status (valid/invalid), signer name, reason for signing, location, and other information. If a document contains multiple signatures (such as, when an already signed document was signed again), the VerifySignature method validates and returns the one that covers the largest portion of the document, which is usually the latest signature.

The following code fragment opens a PDF document from a file, and attempts to validate a signature, if one is present:

Set CM = Server.CreateObject("Persits.CryptoManager")
Set Context = CM.OpenContext("", False)
Set Msg = Context.CreateMessage

Set Doc = Pdf.OpenDocument("c:\somefile.pdf")
Set Sig = Doc.VerifySignature(Msg)

If Sig Is Nothing Then
   Response.Write "No signature found."
Else
   Response.Write "Status = " & Sig.Status & "<BR>"
   Response.Write "Name = " & Sig.Name & "<BR>"
   Response.Write "Reason = " & Sig.Reason & "<BR>"
   Response.Write "Contents = " & Sig.Contents & "<BR>"
End If

Chapter 9: Working with Existing PDFs Chapter 7: Tables
Search AspPDF.com

  This site is owned and maintained by Persits Software, Inc. Copyright © 2003. All Rights Reserved.