50 lines
1.3 KiB
Python
50 lines
1.3 KiB
Python
|
|
import base64
|
|||
|
|
import io
|
|||
|
|
|
|||
|
|
from pyhanko.sign import signers
|
|||
|
|
from pyhanko.sign.general import load_cert_from_pfx
|
|||
|
|
|
|||
|
|
from signing_service.domain.ports.pdf_signer import PDFSignerPort
|
|||
|
|
|
|||
|
|
|
|||
|
|
class PyHankoPDFSigner(PDFSignerPort):
|
|||
|
|
def __init__(self, pfx_password: str) -> None:
|
|||
|
|
self._pfx_password = pfx_password.encode()
|
|||
|
|
|
|||
|
|
def sign(self, pdf_bytes: bytes, certificate: str, password: str,) -> bytes:
|
|||
|
|
"""
|
|||
|
|
certificate: base64-encoded PKCS#12 (PFX)
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
# 1️⃣ Decodificar certificado
|
|||
|
|
pfx_bytes = base64.b64decode(certificate)
|
|||
|
|
|
|||
|
|
# 2️⃣ Cargar clave y certificado
|
|||
|
|
private_key, cert, other_certs = load_cert_from_pfx(
|
|||
|
|
pfx_bytes, password.encode()
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
signer = signers.SimpleSigner(
|
|||
|
|
signing_cert=cert,
|
|||
|
|
signing_key=private_key,
|
|||
|
|
cert_registry=signers.SimpleCertificateStore.from_certs(
|
|||
|
|
other_certs
|
|||
|
|
),
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 3️⃣ Preparar PDF
|
|||
|
|
input_pdf = io.BytesIO(pdf_bytes)
|
|||
|
|
output_pdf = io.BytesIO()
|
|||
|
|
|
|||
|
|
# 4️⃣ Firmar
|
|||
|
|
signers.sign_pdf(
|
|||
|
|
input_pdf,
|
|||
|
|
signers.PdfSignatureMetadata(
|
|||
|
|
field_name="Signature1"
|
|||
|
|
),
|
|||
|
|
signer=signer,
|
|||
|
|
output=output_pdf,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
return output_pdf.getvalue()
|