Skip to main content

Firma digital XMLDSig para Facturación Electrónica Perú

Project description

xfep-sign

Firma digital XMLDSig para Facturación Electrónica Perú (SUNAT).

Parte del ecosistema XFEP. Firma XML generado por xfep-xml con certificado digital .p12/.pfx.

Instalación

pip install xfep-sign

Uso

from xfep.sign import Certificate, XmlSigner

# Cargar certificado digital (.p12 / .pfx)
cert = Certificate.from_file("empresa.p12", "mi_password")

# Firmar XML (bytes de xfep-xml)
signed_xml = XmlSigner.sign(unsigned_xml_bytes, cert)
# signed_xml es bytes UTF-8 con ds:Signature insertado

Cargar certificado desde bytes

with open("empresa.p12", "rb") as f:
    cert = Certificate.from_bytes(f.read(), "mi_password")

Flujo completo con xfep-xml

from xfep.models import Invoice, Client, Detalle, Company
from xfep.xml import XmlBuilder
from xfep.sign import Certificate, XmlSigner

# 1. Crear modelo
invoice = Invoice(
    company_id=1, branch_id=1, serie="F001",
    fecha_emision="2026-02-10", moneda="PEN",
    tipo_operacion="0101", forma_pago_tipo="Contado",
    client=Client(tipo_documento="6", numero_documento="20123456789", razon_social="CLIENTE SAC"),
    detalles=[Detalle(descripcion="Producto", unidad="NIU", cantidad=1,
                      mto_precio_unitario=118, porcentaje_igv=18, tip_afe_igv="10")],
)

# 2. Generar XML
builder = XmlBuilder()
xml_bytes = builder.build(invoice, company)

# 3. Firmar
cert = Certificate.from_file("empresa.p12", "password")
signed_xml = XmlSigner.sign(xml_bytes, cert)

# signed_xml listo para enviar a SUNAT con xfep-ws

API

Certificate

# Desde archivo
cert = Certificate.from_file(path, password)

# Desde bytes
cert = Certificate.from_bytes(data, password)

# Propiedades
cert.private_key   # cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey
cert.x509_cert     # cryptography.x509.Certificate
cert.cert_der_b64  # str — certificado X509 en base64 DER

XmlSigner

signed_xml: bytes = XmlSigner.sign(xml_bytes, certificate)
  • xml_bytes — XML sin firmar (bytes UTF-8, debe contener ext:ExtensionContent placeholder)
  • certificate — Instancia de Certificate
  • Retorna XML firmado como bytes (UTF-8)
  • Lanza ValueError si no encuentra ext:ExtensionContent

CertificateError

Excepción para errores de carga de certificado (archivo inválido, password incorrecto, etc.).

Especificación de firma

La firma XMLDSig insertada sigue la estructura requerida por SUNAT:

Elemento Valor
ds:Signature/@Id SignST
CanonicalizationMethod Exclusive C14N (exc-c14n#)
SignatureMethod RSA-SHA256
DigestMethod SHA-256
Transform Enveloped signature + Exclusive C14N
Ubicación ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent
KeyInfo X509Certificate (base64 DER)

Desarrollo

git clone https://github.com/xpertik/xfep-sign.git
cd xfep-sign

python3.13 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

pytest -v

Los tests generan certificados auto-firmados — no se necesitan archivos externos.

Stack

  • Python >= 3.13
  • cryptography >= 43.0 (PKCS#12, RSA, SHA-256)
  • lxml >= 5.0 (XML parsing, Exclusive C14N)
  • Build: Hatchling
  • Tests: pytest (25 tests)

Parte del ecosistema XFEP

Paquete Estado Descripción
xfep-models v0.1.0 Modelos de datos
xfep-xml v0.1.0 Generación XML UBL 2.1
xfep-sign v0.1.0 Firma digital XMLDSig
xfep-ws pendiente Cliente SOAP/REST para SUNAT
xfep-parser pendiente Parseo de respuestas SUNAT

Licencia

Apache License 2.0 — ver LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

xfep_sign-0.1.0.tar.gz (27.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

xfep_sign-0.1.0-py3-none-any.whl (10.8 kB view details)

Uploaded Python 3

File details

Details for the file xfep_sign-0.1.0.tar.gz.

File metadata

  • Download URL: xfep_sign-0.1.0.tar.gz
  • Upload date:
  • Size: 27.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for xfep_sign-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3dfe601b5df62099bcb1d4b85a8ab9dec8f2b9d4a6f6bc2cddbb1db04dad8317
MD5 34d45cad4c5cfcdfb576a552c3f832ef
BLAKE2b-256 5c90ee48d33f2e99c9b0ae87635bfe719acc7799e47ab6f4767987efbe5aaed3

See more details on using hashes here.

File details

Details for the file xfep_sign-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: xfep_sign-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for xfep_sign-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9906fc74b048095fad4e542e04b9bda7259217b1f3767c4c77585e5856188142
MD5 caeacf98e7b29a96444139618348af6d
BLAKE2b-256 b2b7668c0678cf891648c9e65064e6f5bae39a44a3a12e080d6029c7a732113a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page