Contained Digital Signatures in iOS

PSPDFKit supports a workflow where the creation of a digital signature is split in two phases:

  • First, you can “prepare” a document with a signature form field by stamping a custom signature appearance and reserving space in the PDF for the digital signature.

  • Second, you can “embed” a custom PKCS#7 signature container in a document that was already “prepared” in the first step. The end result is a digitally signed document.

This workflow, which we call contained digital signatures, is especially useful when the cryptographic material to sign a document (keys, certificates) is not available on the platform that executes PSPDFKit.

For the first part, preparing a document, you may call prepare(_:toBeSignedWith:contents:writingTo:completion:) on the PDFSigner class. This preparation step allows customization for the raw content that will fill the digital signature contents before a real digital signature is applied: The PDFSignatureContents protocol is an abstraction for that. If you want to fill the digital signature contents with binary zeroes, pass an instance of the BlankSignatureContents class to prepare(_:toBeSignedWith:contents:writingTo:completion:).

Note that the document generated by the prepare(_:toBeSignedWith:contents:writingTo:completion:) API has two important properties: First, it’s not a valid digitally signed document yet, so it may show errors if you try to validate it with PSPDFKit or any other third-party tool. Second, this document must not be modified in any way, so as to prevent corrupting the digital signature that will be embedded in the final document. The process of embedding the real digital signature is explained next.

For embedding a real digital signature in a document generated by prepare(_:toBeSignedWith:contents:writingTo:completion:), you can call embedSignature(in:with:writingTo:completion:) on the PDFSigner class. You’re responsible for generating a valid digital signature in the cryptographic PKCS#7 format for the prepared document. To do that, pass a custom implementation of PDFSignatureContents to the previously cited method. In your sign(_:) implementation, you’ll receive the part of the document that you need to hash, encrypt, and package into a digital signature. You can call hashDocumentProviderRange(_:hashalgorithm:) on a PDFDocumentProvider instance to help you calculate the hash value of some parts of a PDF document. You can generate the PKCS7 signature container with the help of our PKCS7 class.

You’ll find examples of this API in the Catalog file ContainedDigitalSignaturesExample.swift.