# signing PDF files Adding cryptographic signatures to PDF files ## Details `pdftl` supports high-integrity digital signing of PDF documents. These signatures are applied using **Incremental Updates**, ensuring that the original document structure is preserved and the signature remains cryptographically valid. ### Key Concepts * **Cryptographic Integrity:** Every signature ensures the document has not been modified since the signature was applied. * **Incremental Saving:** `pdftl` saves the document and then appends the signature. This is the industry-standard method for signing PDFs without corrupting existing data. * **Invisible Signatures:** By default, signatures are "invisible." They do not appear as a stamp on the page but are fully recognized by the "Signatures" panel in Adobe Acrobat, `pdfsig`, and other professional validators. ### Command Line Usage To sign a document, you must provide both a private key and a matching certificate in PEM format. #### Basic Signing ```bash pdftl input.pdf output signed_output.pdf \ sign_key path/to/private_key.pem \ sign_cert path/to/certificate.pem ``` #### Arguments | Argument | Description | Required | | --- | --- | --- | | `sign_key` | Path to your private key file (`.pem`). | Yes (for signing) | | `sign_cert` | Path to your certificate file (`.pem`). | Yes (for signing) | |`sign_pass_env` <`var`>|An environment variable with your public certificate passphrase |No| |`sign_pass_prompt` | Ask to be prompted for your public certificate passphrase | No | |`sign_field` <`name`> | The name of a signature field to use (default: `Signature1`)| No | ### Technical Specifications * **Algorithm:** All signatures use **RSA with SHA-256** (OIDs: `1.2.840.113549.1.1.11` and `2.16.840.1.101.3.4.2.1`). * **Sub-Filter:** Uses `adbe.pkcs7.detached`, ensuring compatibility with virtually all PDF viewers. * **ByteRange:** The signature covers the entire file contents. ### Verification You can verify the signature using standard third-party tools. #### Using `pdfsig` (Linux/Poppler) ```bash pdfsig signed_output.pdf ``` **Expected Output:** > `- Signature Validation: Signature is Valid.` #### Using `okular` Open the file and click the "signatures" button that should appear. #### Using Adobe Acrobat 1. Open the PDF in Adobe Acrobat Reader. 2. Look for the **"Signature Panel"** button at the top right. 3. The status should show: *"Signature is valid, signed by [Your Name]."* ### Troubleshooting * **"Missing EKU Error"**: Ensure your certificate includes the **Adobe PDF Signing OID** (`1.2.840.113583.1.1.5`). * **Invalid Signature**: If you attempt to modify a signed PDF using a tool that does not support incremental updates, the signature will break. Always perform your edits (merging, text overlays) **before** or **during** the `pdftl` command that applies the signature. ## Generating files needed for PDF signing Generating a compatible certificate for PDF signing requires a specific extension called **Extended Key Usage (EKU)**. Without it, many PDF viewers (like Adobe Acrobat) will display a warning that the certificate is not intended for digital signatures. You can generate these files using the OpenSSL command line. ### 1. Create a Configuration File Standard OpenSSL commands for "web" certificates don't include the Adobe-specific OID. Create a small file named `pdf_cert.conf`: ```ini [req] distinguished_name = req_distinguished_name x509_extensions = v3_ext prompt = no [req_distinguished_name] CN = PDTTL Test Certificate [v3_ext] # This OID (1.2.840.113583.1.1.5) tells viewers this is a PDF Signing cert extendedKeyUsage = 1.2.840.113583.1.1.5 ``` ### 2. Generate an Unencrypted Key & Cert If you want to test the basic functionality without a passphrase (the "unencrypted" path): ```bash openssl req -x509 -newkey rsa:2048 -nodes -keyout test_key.pem -out test_cert.pem -days 365 -config pdf_cert.conf ``` ### 3. Generate an Encrypted Key To generate a password protected key: ```bash # This will prompt you for a password during generation openssl req -x509 -newkey rsa:2048 -keyout test_key_encrypted.pem -out test_cert.pem -days 365 -config pdf_cert.conf ``` ### Verifying the Certificate Before using it in `pdftl`, you can verify that the "PDF Signing" extension was correctly embedded: ```bash openssl x509 -in test_cert.pem -text -noout | grep -A 1 "Extended Key Usage" ``` **Expected Output:** > `X509v3 Extended Key Usage:` > `1.2.840.113583.1.1.5` ### Summary of Files * **`test_key.pem`**: Your private key. Keep this secret. * **`test_cert.pem`**: Your public certificate. This is what gets embedded in the PDF so others can verify your signature. *Source: pdftl.output.sign* *Read online: [https://pdftl.readthedocs.io/en/latest/general/signing.html](https://pdftl.readthedocs.io/en/latest/general/signing.html)* *Type: HelpTopic*