Tuesday, January 15, 2008

Reading and Writing Secure PDF Files

One of the most common unattended batch PDF processes is to apply standardized access permissions and encryption to all documents. This may be done as a stand-alone utility that uses a watched folder on your network or integrated into your document workflow system.

You can use PdfDocument to open an encrypted PDF file, assuming that you know either the owner or user password. With a Solid Framework Tools license you can write changes back to the PDF which means you can add, remove or alter the security settings.

Add or Remove PDF Security

The PdfDocument class is all you need in order to master PDF security using Solid Framework. The steps involved are:
  • Open() - opening an existing PDF file (with or without a password)
  • EncryptionAlgorithm - choosing an encryption algorithm
  • OwnerPassword and UserPassword - setting new passwords
  • Permissions: setting user access permissions for the PDF file
  • Save() or SaveAs() - saving the modified PDF file
PdfDocument and Document classes

As usual with these examples, please start by getting one of the samples like pdfcreator working. That will ensure that your license is working. Then we'll remove the code in the body of the Main method. Keep the License.Import(..) call.

Make sure you have the following using statements:

using SolidFramework;
using SolidFramework.Plumbing;using SolidFramework.Pdf;
using SolidFramework.Pdf.Plumbing;

For convenience, we can still use the InputPath and OutputPath from JobSettings. Edit JobSettings to make InputPath point to your existing PDF file. Make OutputPath point to where you want the resulting PDF file stored.

Create a new PdfDocument as follows:

PdfDocument document = new PdfDocument();

Set the properties including the owner password if the file is protected. The user password would give you readonly access to the file. To modify it, you need to use the owner password.

document.Path = JobSettings.Default.InputPath;document.OwnerPassword = "owner";

And then load the file.



If the file was already secure then its EncryptionAlgorithm will be set. You have several choices but you cannot leave this property Undefined if you wish to use password security.

PDF encryption algorithm
RC440Bit is of legacy interest only. In the past there were performance issues and there are also export compliance issues related to the more secure 128 bit algorithms. AES is a more recent addition to the PDF standard than RC4 and RC4 is still a proprietary algorithm owned by RSA. It is also the most commonly used algorithm.

Make your choice and set it like this:

document.EncryptionAlgorithm = EncryptionAlgorithm.RC4128Bit;

OwnerPassword and UserPassword
There are two levels of access to a PDF file:

  • Owner - the author (owner) has this level of access to modify the document permissions allowed to users. The owner always has all permissions.
  • User - the user's permissions are restricted by the owner.
We'll set both passwords so that we can examine all the security features. It is possible to create PDF files with only the owner password. Obviously you will want to use much stronger passwords that include the odd number or special character. Remember that passwords are also case sensitive.

document.OwnerPassword = "newowner";
document.UserPassword = "user";


PDF access permissions
These values can be or'd to give any combination of permissions to your users like this:
document.Permissions =
AccessPermissions.Printing | AccessPermissions.AccessForDisabilities;
If you set the UserPassword then users will need to enter this password when they open the PDF file. After that, the restrictions based on AccessPermissions apply.
If you leave the UserPassword blank then users will not need to enter any password but the document will still be restricted by AccessPermissions. Opening the document and entering the owner password will give full permissions to the owner.

Save or SaveAsNow it is time to save your PDF document to a new file. Assuming your OutputPath is set to a good location, you just need two more lines of code. Without ForceOverwrite there will be an exception thrown if the file already exists.
document.OverwriteMode = OverwriteMode.ForceOverwrite;

Complete Sample Snippet

// createPdfDocument document = new PdfDocument();

// set
document.Path = JobSettings.Default.InputPath;
document.OwnerPassword = "owner";

// call

// set
document.EncryptionAlgorithm = EncryptionAlgorithm.RC4128Bit;
document.OwnerPassword = "newowner";
document.UserPassword = "user";
document.Permissions = AccessPermissions.Printing | AccessPermissions.AccessForDisabilities;
document.OverwriteMode = OverwriteMode.ForceOverwrite;

// call