How make digital sign in a pdf with Python

4.8k views Asked by At

I want to sign a PDF with a p12 certificate in Python, but I don't know how to start, what libraries to use, or how to do it.

I have a good understanding of how digital signatures work, but I'd like to do it in Python. I would be grateful for any assistance.

I was seeing examples with endesive, but I think that endesive uses RSA, and I want to do it with ECDSA.

I don't know if it doesn't matter, because the p12 contains everything.

import datetime
from cryptography.hazmat import backends
from cryptography.hazmat.primitives.serialization import pkcs12

from endesive.pdf import cms

#nuevo = cms.sign()



def firmar(contraseña, certificado, pdf):
    date = datetime.datetime.utcnow() - datetime.timedelta(hours=12)
    date = date.strftime("D:%Y%m%d%H%M%S+00'00'")
    dct = {
        "aligned": 0,
        "sigflags": 3,
        "sigflagsft": 132,
        "sigpage": 0,
        "sigbutton": True,
        "sigfield": "Signature1",
        "auto_sigfield": True,
        "sigandcertify": True,
        "signaturebox": (470, 840, 570, 640),
        "signature": "Aquí va la firma",
        # "signature_img": "signature_test.png",
        "contact": "[email protected]",
        "location": "Ubicación",
        "signingdate": date,
        "reason": "Razón",
        "password": contraseña,
    }
    # with open("cert.p12", "rb") as fp:
    p12 = pkcs12.load_key_and_certificates(
        certificado.read(), contraseña.encode("ascii"), backends.default_backend()
    )

    print(p12[0])
    print(p12[1])
    print(p12[2])
    #datau = open(fname, "rb").read()
    datau = pdf.read()
    datas = cms.sign(datau, dct, p12[0], p12[1], [], "sha256")
    #nuevo = cms.sign()
    return datau, datas
    """
    fname = "test.pdf"
    with open(fname, "wb") as fp:
        fp.write(datau)
        fp.write(datas)
    """
1

There are 1 answers

0
mval On

PyHanko supports ECDSA---among several other signing algorithms, pretty much everything that the latest version of the PDF standard (+extensions) allows.

Here's a very basic PKCS#12 usage example:

from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
from pyhanko.sign import signers


signer = signers.SimpleSigner.load_pkcs12(
    pfx_file='signer.pfx', passphrase=b'secret'
)

with open('document.pdf', 'rb') as doc:
    w = IncrementalPdfFileWriter(doc)
    out = signers.sign_pdf(
        w, signers.PdfSignatureMetadata(field_name='Signature1'),
        signer=signer,
    )

    # do stuff with 'out'...

In this case, the signing algorithm will be autodetected based on the kind of key in the PKCS#12 file, so there's no need to explicitly specify ECDSA. For more advanced usage, see the documentation.

(Full disclosure: I wrote/maintain pyHanko)