Introduction to Encryption

PDF password encryption

The default PDF password encryption is supported. If you open a PDF document that is password protected, PSPDFKit will show a password prompt to unlock. (The password can also be set programmatically via unlockWithPassword:.)

By selecting the "Acrobat 3 And Later" option, when creating an encrypted PDF, a low encryption level (40‑bit RC4) is used, while the other options use a high encryption level (128‑bit RC4 or AES). "Acrobat 9.0 And Later" encrypts the document using the AES encryption algorithm with a 256-bit key size. iOS, including version 8, does not yet support the Acrobat 9.0+ style encryption.

Owner and User Passwords

A PDF file can have multiple security-related options set. The owner password generally controls the editing of a document and is required as soon as you want to encrypt a document of any kind. The user password prevents users from viewing the PDF. It is optional but if you specify it you also need to specify an owner password. Check out our Document Processing Guide for more details on how to create a password-protected document using PSPDFKit.

Encryption algorithms

PSPDFKit supports RC4 and AES encryption algorithms.

RC4 is a proprietary encryption algorithm of RSA Security Inc. It is a symmetric stream cipher, ie. the same algorithm is used for both encryption and decryption, and the algorithm does not change the length of the data.

AES support was introduced with PDF 1.6. It is a symmetric block cipher, ie. the same algorithm is used for both encryption and decryption, and the length of the data when encrypted is rounded up to a multiple of the block size, which is fixed in this implementation to always be 16 bytes.

Encryption Algorithm PDF and Acrobat version
RC4 40-bit PDF 1.1 - 1.3 (Acrobat 2-4)
RC4 128-bit PDF 1.4 - 1.5 (Acrobat 5-6)
AES 128-bit PDF 1.6 - 1.7 = ISO 32000-1 (Acrobat 7-8)

PSPDFKit supports fast, in-memory AES256 decryption

PSPDFKit is able to add an additional layer of security with support of state-of-the-art, fast, in-memory AES256 decryption using the PSPDFAESCryptoDataProvider class. You can encrypt the whole file with a password+salt and by using 10,000 PBKDF iterations, the file is well protected against brute-force attacks (unlike solutions from Adobe). We also provide the "AESCryptor" Mac app that encrypts your PDF documents. Unlike NSData-based solutions, the PDF is never fully decrypted and this even works with very large (> 500MB) documents. The file also will never be written out unencrypted to disk and the cache is automatically disabled for encrypted content.

Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Note: For shipping apps, you need to protect this string better,
// making it harder for hacker to simply disassemble and receive the key
// from the binary. Or add an internet service that fetches the key from
// an SSL-API. But then there's still the slight risk of memory dumping
// with an attached gdb. Or screenshots. Security is never 100% perfect;
// but using AES makes it way harder to get the PDF. You can even
// combine AES and a PDF password.
let passphrase = "afghadöghdgdhfgöhapvuenröaoeruhföaeiruaerub"
let salt = "ducrXn9WaRdpaBfMjDTJVjUf3FApA6gtim0e61LeSGWV9sTxB0r26mPs59Lbcexn"

// Generate the crypto data provider.
guard let encryptedPDF = Bundle.main.resourceURL?.appendingPathComponent("encrypted.pdf.aes"),
    let cryptoDataProvider = PSPDFAESCryptoDataProvider(url: encryptedPDF, passphraseProvider: { passphrase }, salt: salt, rounds: PSPDFDefaultPBKDFNumberOfRounds) else {
        return
}

// Create the PSPDFDocument.
let document = PSPDFDocument(dataProviders: [cryptoDataProvider])
document.uid = encryptedPDF.lastPathComponent // Manually set a UID for encrypted documents.

// `PSPDFAESCryptoDataProvider` automatically disables `useDiskCache` to restrict using the disk cache for encrypted documents.
// If you use a custom crypto solution, don't forget to disable `useDiskCache` on your custom data provider or on the document,
// in order to avoid leaking out encrypted data as cached images.
// document.useDiskCache = false

// Show the controller.
let pdfController = PSPDFViewController(document: document)
navigationController.pushViewController(pdfController, animated: true)
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Note: For shipping apps, you need to protect this string better,
// making it harder for hacker to simply disassemble and receive the key
// from the binary. Or add an internet service that fetches the key from
// an SSL-API. But then there's still the slight risk of memory dumping
// with an attached gdb. Or screenshots. Security is never 100% perfect;
// but using AES makes it way harder to get the PDF. You can even
// combine AES and a PDF password.
NSString *passphrase = @"afghadöghdgdhfgöhapvuenröaoeruhföaeiruaerub";
NSString *salt = @"ducrXn9WaRdpaBfMjDTJVjUf3FApA6gtim0e61LeSGWV9sTxB0r26mPs59Lbcexn";

// Generate the crypto data provider.
NSURL *encryptedPDF = [[[NSBundle mainBundle] resourceURL] URLByAppendingPathComponent:@"encrypted.pdf.aes"];
PSPDFAESCryptoDataProvider *cryptoDataProvider = [[PSPDFAESCryptoDataProvider alloc] initWithURL:encryptedPDF passphraseProvider:^{ return passphrase; } salt:salt rounds:PSPDFDefaultPBKDFNumberOfRounds];

// Create the PSPDFDocument.
PSPDFDocument *document = [[PSPDFDocument alloc] initWithDataProviders:@[cryptoDataProvider]];
document.UID = encryptedPDF.lastPathComponent; // Manually set a UID for encrypted documents.

// `PSPDFAESCryptoDataProvider` automatically disables `useDiskCache` to restrict using the disk cache for encrypted documents.
// If you use a custom crypto solution, don't forget to disable `useDiskCache` on your custom data provider or on the document,
// in order to avoid leaking out encrypted data as cached images.
// document.useDiskCache = NO;

// Show the controller.
PSPDFViewController *pdfController = [[PSPDFViewController alloc] initWithDocument:document];
[self.navigationController pushViewController:pdfController animated:YES];