Table of Contents

How to migrate to the Docotic.Pdf Encryption API introduced in 2021

At the beginning of 2021, we introduced significant changes to the Encryption API of Docotic.Pdf library. This document provides a migration guide from the older to the new API. It provides code snippets for the most common use cases using both versions of the API.

We changed the Encryption API to add support for public-key encrypted PDF documents. Such documents are also referred to as documents protected with Public-Key Security Handlers. Or certificate encrypted documents.

Also, the updated API makes some not so obvious connections in the older API more clear. And it provides more information, too.

Check if document is encrypted

The older version only allowed to check if a password is required to open a document.

// This code uses obsolete API

bool passwordProtected = PdfDocument.IsPasswordProtected(fileName);
if (passwordProtected)
    Console.WriteLine("Requires password to open");
else
    Console.WriteLine("Does not require password to open");

With the new version, you can check if a document is encrypted and what kind of encryption handler was used to encrypt it.

var info = PdfDocument.GetEncryptionInfo(fileName);
if (info == null)
    Console.WriteLine("Is not encrypted");
else if (info is PdfStandardEncryptionInfo standardInfo)
    Console.WriteLine("Is encrypted with a password");
else if (info is PdfPublicKeyEncryptionInfo publicKeyInfo)
    Console.WriteLine("Is encrypted with a digital certificate(s)");

For a document encrypted with a password, you can check if the password is required to open the document. Many password-protected documents can be opened without a password. Often a password is only needed for the "owner" mode.

if (standardInfo.RequiresPasswordToOpen)
    Console.WriteLine("Can not be opened without a password");
else
    Console.WriteLine("Does not require a password");

For a document encrypted with certificates, it is possible to get information about recipients of the document. In other words, it is possible to check what certificates can unlock the document. Please note that permissions may vary for different recipients.

// the Recipients property contains information about certificates
// that can be used to decrypt the document
foreach (var recipient in publicKeyInfo.Recipients)
    Console.WriteLine(recipient.SerialNumber);

Related sample code:
Check if PDF document is password protected

Open encrypted document

Previously, Docotic.Pdf only allowed to open protected documents encrypted with a password.

// This code uses obsolete API

using (PdfDocument document = new PdfDocument(fileName, "password"))
{
    // do something with the decrypted document
}

With the new Encryption API, it is also possible to open certificate-protected documents.

// If the document is protected with a password
using (PdfDocument document = new PdfDocument(fileName, new PdfStandardDecryptionHandler("password")))
{
    // do something with the decrypted document
}

// If the document is protected with a certificate
var handler = new PdfPublicKeyDecryptionHandler();
using (PdfDocument document = new PdfDocument(fileName, handler))
{
    // do something with the decrypted document
}

Related sample code:
Open PDF document encrypted with a certificate in C# and VB.NET

Check permissions

To check access permissions, you would need a document first. It does not matter if the document is created from scratch, or if you opened it from a file or stream.

// This code uses obsolete API

// create a new or open an existing document
using (PdfDocument document = ...)
{
    Console.WriteLine("Document permissions = {0}", document.Permissions);
}

With the new API, the only difference is the property name.

// create a new or open an existing document
using (PdfDocument document = ...)
{
    Console.WriteLine("Document permissions = {0}", document.GrantedPermissions);
}

Encrypt document

Previously, properties of the PdfDocument class were used to encrypt a document and set up permissions for it.

// This code uses obsolete API

using (PdfDocument document = ...)
{
    // an owner password should be set in order to use user access permissions
    document.OwnerPassword = "owner";
    document.UserPassword = "user";
    document.Permissions.Flags = PdfPermissionFlags.None;

    document.Save(outputFileName);
}

In the new API, similar properties are encapsulated in an encryption handler instance.

using (PdfDocument document = ...)
{
    PdfStandardEncryptionHandler handler = new PdfStandardEncryptionHandler("owner", "user");
    handler.UserPermissions.Flags = PdfPermissionFlags.None;
    document.SaveOptions.EncryptionHandler = handler;

    document.Save(outputFileName);
}

Related sample code:
Encrypt PDF with a password in C# and VB.NET
Protect PDF document with AES
Protect PDF document with a certificate
Set up PDF permissions in C# and VB.NET

Compare documents

Previously, the DocumentsAreEqual method had the password parameter. That parameter was used to compare encrypted documents. For not encrypted documents the empty string was used for the password parameter.

// This code uses obsolete API

// comparing encrypted documents
bool areEqual = PdfDocument.DocumentsAreEqual("first.pdf", "second.pdf", "password");

// comparing NOT encrypted documents
bool areEqual = PdfDocument.DocumentsAreEqual("first.pdf", "second.pdf", string.Empty);

The current API requires to use a decryption handler when comparing encrypted documents. For not encrypted documents, please use an overload that does not accept a handler.

// comparing encrypted documents
PdfDecryptionHandler handler = new PdfStandardDecryptionHandler("password");
bool areEqual = PdfDocument.DocumentsAreEqual("first.pdf", "second.pdf", handler);

// comparing NOT encrypted documents
bool areEqual = PdfDocument.DocumentsAreEqual("first.pdf", "second.pdf");

Append documents

The Append method had the password parameter in the previous version of the API. That parameter was used to append password-protected documents.

// This code uses obsolete API

using (PdfDocument document = ...)
    document.Append("another.pdf", "password");

The new API requires to use a decryption handler when appending encrypted documents. You can append a not encrypted document, using an overload that does not accept a handler.

using (PdfDocument document = ...)
    document.Append("another.pdf", new PdfStandardDecryptionHandler("password"));

using (PdfDocument document = ...)
    document.Append("anotherNotEncrypted.pdf");