VerifactuMidAPI/documentacion/certificado_pruebas.md

4.7 KiB

Certificado Digital para VeriFactu

Introducción

VeriFactu requiere autenticación mTLS: la API presenta tu certificado al conectarse con la AEAT. Tanto en pruebas como en producción se usa el mismo certificado real — no existe un certificado especial de pruebas.

Certificado válido: FNMT Persona Física

El Certificado de Ciudadano (Persona Física) de la FNMT es gratuito y válido tanto para el entorno de pruebas como para producción.

Obtención gratuita — opciones:

  1. Presencial en oficina AEAT (recomendado): llevar el DNI a cualquier delegación de la Agencia Tributaria. Trámite en 2 minutos, sin cita previa en la mayoría.
  2. Con DNIe + NFC: si tu DNI es posterior a 2015, puedes hacer todo el proceso online desde sede.fnmt.gob.es usando el chip NFC del DNI con tu móvil o un lector de tarjetas.
  3. Videollamada (coste 2,99 € + IVA): servicio de identificación remota sin desplazamiento.

La renovación online es gratuita mientras el certificado esté vigente (hasta 60 días antes de su vencimiento).

Verificar el certificado (PowerShell)

$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2(".\data\certs\personal.p12", "TU_CONTRASEÑA")
Write-Host "Válido desde:" $cert.NotBefore
Write-Host "Válido hasta:" $cert.NotAfter
Write-Host "Asunto:"       $cert.Subject
Write-Host "Vigente:"      ($cert.NotAfter -gt (Get-Date))

El campo Subject debe contener OU=CIUDADANOS (persona física) y el NIF del titular.

Registrar Nuevo Certificado

Una vez tengas el archivo .p12:

1. Copiar a una ubicación segura

cp micertificado.p12 ./data/certs/

2. Actualizar config.yml

certificates:
  storage_path: ./data/certs/
  cert_file: ./data/certs/nuevo_cert.p12
  cert_password: TU_CONTRASEÑA

3. Convertir certificado

La API necesita el certificado en formato PEM:

python convert_cert.py ./data/certs/nuevo_cert.p12 TU_CONTRASEÑA

Esto genera:

  • cert_key.pem (clave privada)
  • cert_cert.pem (certificado público)

4. Reiniciar API

# Detener API
taskkill /F /IM main.exe

# Iniciar
go run main.go

5. Probar

python test_invoice.py

Estructura de Directorios

VerifactuMidAPI/
├── data/
│   └── certs/
│       ├── personal.p12      # Tu certificado
│       ├── cert_key.pem     # Generado automáticamente
│       └── cert_cert.pem   # Generado automáticamente
└── config.yml              # Configuración

Problemas Comunes

"pkcs12: expected exactly two safe bags in the PFX PDU"

El archivo .p12 contiene más de un certificado (cadena completa con CA intermedias). La librería Go pkcs12 espera solo el certificado de cliente y la clave privada.

Solución: Extraer solo el certificado de cliente y crear un nuevo P12:

# Extraer clave privada
openssl pkcs12 -in original.p12 -nocerts -nodes -passin pass:PASSWORD -out key.pem

# Extraer solo el certificado de cliente
openssl pkcs12 -in original.p12 -clcerts -nokeys -passin pass:PASSWORD -out client_cert.pem

# Crear nuevo P12 simplificado
openssl pkcs12 -export -out personal.p12 -inkey key.pem -in client_cert.pem \
  -passout pass:PASSWORD -name "personal" -legacy -certpbe PBE-SHA1-3DES -keypbe PBE-SHA1-3DES

"pkcs12: unknown digest algorithm: 2.16.840.1.101.3.4.2.1"

La librería Go pkcs12 no soporta cifrado SHA-256 en archivos P12. Se necesita usar cifrado legacy (SHA1/3DES).

Solución: Recrear el P12 con cifrado legacy (ver comando -legacy -certpbe PBE-SHA1-3DES -keypbe PBE-SHA1-3DES arriba).

"403 Forbidden"

  • El certificado no está autorizado en el entorno de pruebas
  • O el certificado es de producción y estás en test

"Certificate expired"

  • El certificado ha caducado
  • Solicitar uno nuevo

"Invalid password"

  • La contraseña del .p12 es incorrecta

"tls: failed to find any PEM data"

  • Error al convertir el certificado
  • Ejecutar python convert_cert.py manualmente para ver el error

Siguientes Pasos

  1. Obtener certificado de pruebas FNMT
  2. Registrar en la API
  3. Probar con python test_invoice.py
  4. Verificar que devuelve estado "Correcto" (no "Correcto (local)")

Recursos