Digital Signatures


What are Digital Signatures

A digital signature is an electronic fingerprint, uniquely identifying the signing person. For more information on digital signatures please look at Digital Signatures in PDF. Also have a look at Section 12.8 Digital Signatures of the PDF 1.7 Specification.

For general information on how digital signatures work have a look here.

Considerations

Currently PSPDFKit only allows signing existing signature form elements. You therefore will need a template with an existing signature form field.

Supported signing algorithms are:

  • RSA / SHA256

You can use a self-signed certificate for testing purposes, but you will need to make sure that certificate is trusted by all the devices the PDF is opened on (including PCs/Macs with Acrobat). A self signed certificate will probably also generate warnings about it's keyUsage extension (the self-signed certificate must permit certificate signing - keyCertSign, see RFC 5280).

In production always use a certificate from a valid Certificate Authority. Make sure that the certificate's keyUsage has digitalSignature permission set (see RFC 5280).

How to create Digital Signatures

To create a digital signature, you need 2 things. An X509 certificate that contains your public key and signer information - and your private key. The signing process produces the signature by encrypting the message digest from the PDF file with a private key. The certificate with its public key is added to the signature and saved in the PDF file. PSPDFKit provides a PSPDFPKCS12Signer for your convenience that loads a certificate with public and private key from a p12 archive. If you want to customize the signing process, you need to subclass PSPDFSigner.Keep in mind that certificates installed by user via opening .p12 container with built-in apps (via "Install Profile") will go to Apple access group and will only be available to Apple-provided apps such as Safari or Mail. See Apple Technical Q&A for more details and a suggested workaround - Technical Q&A QA1745

Here is an example of how to register a PSPDFPKCS12Signer

Copy
1
2
3
4
5
6
7
8
9
// p12Data is an p12 archive NSData object
PSPDFPKCS12 *p12 = [[PSPDFPKCS12 alloc] initWithData:p12Data];

// Create a signer with a display name. the display name will shop up in the list of identities when you tap on a signature form field
PSPDFPKCS12Signer *p12Signer = [[PSPDFPKCS12Signer alloc] initWithDisplayName:@"John Appleseed" PKCS12:p12];

// Finally register your signer with the signature manager
PSPDFSignatureManager *signatureManager = PSPDFKit.sharedInstance.signatureManager;
[signatureManager registerSigner:p12Signer];
Copy
1
2
3
4
5
6
7
8
9
// p12Data is an p12 archive NSData object
let p12 = PSPDFPKCS12(data: p12Data)

// Create a signer with a display name. the display name will shop up in the list of identities when you tap on a signature form field
let p12Signer = PSPDFPKCS12Signer(displayName: "John Appleseed", pkcs12: p12)

// Finally register your signer with the signature manager
let signatureManager = PSPDFKit.sharedInstance.signatureManager
signatureManager.register(p12Signer)

A PSPDFUnsignedFormElementViewController will be automatically created when tapping on a signature form element, after you registered a signer:

PSPDFUnsignedFormElementViewController

PSPDFKit also needs to be able to verify the validity of signatures. Validation of the signature consists of two steps. First is to check if the certificate from the signature (embedded on signing) can be trusted. In order to do it we need to provide the trusted certificate (from the authority that issued it root CA certificate or intermediate CA certificate). The second step is the signature verification. It's a decryption of a signature with a public key from the certificate embedded in the PDF file (on signing) and compare it with the message digest built from the PDF file excluding the signature itself.

Here is an example on how to provide the trusted certificate:

Copy
1
2
3
4
5
6
7
8
9
10
11
// Load a certificate (with a public key) from a p7 archive
NSData *certificateData = [NSData dataWithContentsOfURL:p7URL];

NSError *error = nil;
NSArray *certificates = [PSPDFX509 certificatesFromPKCS7Data:certData error:&err];

// Don't forget to check for errors here

for (PSPDFX509 *certificate in certificates) {
    [signatureManager addTrustedCertificate:certificate];
}
Copy
1
2
3
4
5
6
7
8
9
10
11
do {
    // Load a certificate (with a public key) from a p7 archive
    let certificateData = try Data(contentsOf: p7URL)
    let certificates = try PSPDFX509.certificatesFromPKCS7Data(certificateData)

    for certificate in certificates {
        signatureManager.addTrustedCertificate(certificate)
    }
} catch {
    // Don't forget to check for errors here
}

In PSPDFKit Demo app in the section FORMS AND DIGITAL SIGNATURES see the Digital signing process for the example of interactive (user driven) signing process and signature validation. In the Automated digital signing process see the example of non-interactive signing process.

Creating a custom signer

In order to customize the signing process you can subclass PSPDFSigner. Then you register the signer with the signature manager just like described above. Please have a look at the documentation in the PSPDFSigner header file for more information on what methods you need to override.

Was this page helpful? We're happy to answer any questions.