Before we get started, have you tried our new Python Code Assistant? It's like having an expert coder at your fingertips. Check it out!
A digital signature added to a PDF document is equivalent to an ink signature on a paper document, however the former is much more secure.
A digital signature guarantees the integrity of a PDF document and certifies that this document has not been modified by an unknown person. It can replace your handwritten signature to speed up virtually any paper-driven, manual signature process and to accelerate workflows.
Download: Practical Python PDF Processing EBook.
In this tutorial, you will learn:
The following components are required:
The purpose of this tutorial is to develop a lightweight command-line-based utility, through Python-based modules in order to digitally sign one or a collection of PDF files located under a specific path.
Related: How to Watermark PDF Files in Python.
To get started, let's install the libraries:
In the end, our folder structure will look like the following:
The
signature.jpg
file represents a specimen signature:
The
"Letter of confirmation.pdf"
file represents a sample PDF file to be signed.
Let's get started, open up a new Python file and name it sign_pdf.py
or whatever:
The above function creates a public/private key pair to use when generating the self-signed certificate in order to perform asymmetric encryption.
Next, making a function to create a self-signed certificate:
Master PDF Manipulation with Python by building PDF tools from scratch. Get your copy now!
Download EBookThis function creates a self-signed certificate that does not require to be signed by a certificate authority.
This function will assign the following attributes to the certificate:
Now let's make a function that uses both functions to generate a certificate:
This function performs the following:
"private_key.pem"
under the static
folder."certificate.cer"
under the static
folder."public_key.pem"
under the static
folder."container.pfx"
combining the private key and the certificate and places it under the static
folder.Note that the private key should not be printed in the console. However, it is included in the summary dictionary (that will be printed) for demonstration purposes, make sure you remove the private key from the console output if you're serious about this.
Now that we have the core function to generate a certificate, let's make a function to sign a PDF file:
The sign_file()
function performs the following:
Make sure you have the certificates under the static
folder (we'll see how to generate this later).
Optionally, the following function is useful for signing all PDF files within a specific folder:
This function is targeted to sign the PDF files of a specific folder.
It loops throughout the files of the specified folder either recursively or not depending on the value of the recursive
parameter and processes these files one by one. It accepts the following parameters:
input_folder
: The path of the folder containing the PDF files to process.signatureID
: The identifier of the signature widget to create.x_coordinate
and y_coordinate
: The coordinates indicating the location of the signature. pages
: The range of the pages to sign.recursive
: whether to run this process recursively by looping across the subfolders or not.Alright, now we have everything, let's make the necessary code for parsing command-line arguments:
The is_valid_path()
function validates a path inputted as a parameter and checks whether it is a file or a directory.
The parse_args()
function defines and sets the appropriate constraints for the command line arguments to be specified by the user when running this utility.
I will describe hereafter the defined arguments:
--load
or -l
: Initialize the configuration settings by generating a self-signed certificate. This step should be executed once or on a need basis.--input_path
or -i
: Used to input the path of the file or the folder to process, this parameter is associated with the is_valid_path()
function that is previously defined.--signatureID
or -s
: The identifier to assign to the signature widget. (in case multiple signees need to sign off the same PDF document).--pages
or -p
: The pages to sign off.--x_coordinate
or -x
and --y_coordinate
or -y
: Specifies the location of the signature on the page.--output_file
or -o
: The path of the output file. Filling in this argument is constrained by the selection of a file as input, not a directory.--recursive
or -r
: Whether to process a folder recursively or not. Filling in this argument is constrained by the selection of a directory. Master PDF Manipulation with Python by building PDF tools from scratch. Get your copy now!
Download EBookWriting the main code now:
The above represents the main function of our program which calls the respective functions depending on the load parameter or the path selected.
Let’s test our program:
First, let's pass --help
to see the available command-line arguments to pass:
Output:
Alright, let's first generate a self-signed certificate:
Once executed, you will notice that the related files were created beneath the static
folder:
Moreover, you will outline the following summary on your console:
As you can see, private and public keys were successfully generated, as well as the certificate. Again, as noted earlier. If you're using this code, you should exclude the private key from the summary dictionary so it won't be printed to the console.
Now let’s sign the document entitled "Letter of confirmation.pdf"
placed under the static folder:
The following summary will be displayed on the console:
The document will be updated in "Letter of confirmation_signed.pdf"
as follows:
When you click on the signature field highlighted, you will notice the warning message displayed hereafter:
The reason for this warning is that the new self-signed certificate is not yet trusted by Acrobat Reader. Press on the Signature Properties button and you will see the details of the self-signed certificate.
Note: Please refer to the enclosed appendix detailing the operating instructions for trusting the self-signed certificate by Adobe Reader.
You can also specify the -p
option to sign multiple pages within a PDF file, something like:
Or signing multiple PDF files included within a folder:
Digitally signing documents saves time, reduces the need for paper-driven processes, and offers you the flexibility to approve a document from almost anywhere.
I hope you enjoyed this article and helped you build your tools!
Check the complete code here.
For more PDF handling guides on Python, you can check our Practical Python PDF Processing EBook, where we dive deeper into PDF document manipulation with Python, make sure to check it out here if you're interested!
Related tutorials:
After signing a PDF file (i.e. "Letter of confirmation_signed.pdf"
) and then opening it in Adobe Reader, the following message ("At least one signature has problems") may be shown below the toolbar:
Indeed, this message does not indicate that the digital signature is invalid or corrupt but it means that the digital signature added using the self-signed certificate cannot be automatically validated by Adobe Reader because the certificate is not in the list of Trusted identities that Adobe uses to validate the signature.
Please follow the steps exhibited in the following screen-shots in order to add the self-signed certificate into Adobe’s list of Trusted identities:
static
folder:Now close and re-open the PDF document:
Click on the signature field:
And there you go, it's a valid signature!
Check the full code here.
Finally, for more PDF handling guides on Python, you can check our Practical Python PDF Processing EBook, where we dive deeper into PDF document manipulation with Python, make sure to check it out here if you're interested!
Learn also: How to Use Hashing Algorithms in Python using hashlib.
Happy coding ♥
Let our Code Converter simplify your multi-language projects. It's like having a coding translator at your fingertips. Don't miss out!
View Full Code Auto-Generate My Code
Got a coding query or need some guidance before you comment? Check out this Python Code Assistant for expert advice and handy tips. It's like having a coding tutor right in your fingertips!