2026-04-17 11:03:06 +00:00
|
|
|
# Seguridad y Certificados
|
|
|
|
|
|
|
|
|
|
## Certificados Digitales
|
|
|
|
|
|
|
|
|
|
### Requisitos
|
|
|
|
|
|
|
|
|
|
- Certificado cualificado de firma electrónica (eIDAS)
|
|
|
|
|
- Formato **.p12** o **.pfx**
|
|
|
|
|
- Contraseña válida
|
|
|
|
|
|
|
|
|
|
### Validación
|
|
|
|
|
|
2026-05-19 20:03:28 +00:00
|
|
|
La API valida nativamente (sin scripts externos):
|
|
|
|
|
1. **Formato PKCS#12 válido**
|
2026-04-17 11:03:06 +00:00
|
|
|
2. **Contraseña correcta**
|
2026-05-19 20:03:28 +00:00
|
|
|
3. **Fechas de validez** (no expirado, no futuro)
|
2026-04-17 11:03:06 +00:00
|
|
|
4. **Días hasta expiración**
|
|
|
|
|
|
|
|
|
|
### Almacenamiento
|
|
|
|
|
|
2026-05-19 20:03:28 +00:00
|
|
|
El certificado se envía como base64 en el JSON de registro:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"cert_name": "mi-cert",
|
|
|
|
|
"cert_file": "BASE64_P12_CONTENT",
|
|
|
|
|
"password_encrypted": "..."
|
|
|
|
|
}
|
2026-04-17 11:03:06 +00:00
|
|
|
```
|
|
|
|
|
|
2026-05-19 20:03:28 +00:00
|
|
|
1. El cliente envía el certificado como base64
|
|
|
|
|
2. Se valida el PKCS#12 nativamente en Go
|
|
|
|
|
3. Se guarda en `data/certs/<cert_name>.p12`
|
|
|
|
|
4. Se genera un token de sesión
|
2026-04-17 11:03:06 +00:00
|
|
|
|
|
|
|
|
## Cifrado RSA
|
|
|
|
|
|
|
|
|
|
### Porqué RSA
|
|
|
|
|
|
|
|
|
|
- Las contraseñas de certificados no se envían en texto plano
|
|
|
|
|
- El cliente cifra la contraseña con la clave pública de la API
|
|
|
|
|
- Solo la API puede descifrarla (tiene la clave privada)
|
|
|
|
|
|
|
|
|
|
### Proceso
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
1. API genera par de claves RSA al inicio
|
|
|
|
|
2. Cliente pide /api/v1/auth/public-key
|
|
|
|
|
3. Cliente cifra password con clave pública
|
|
|
|
|
4. Cliente envía cifrada
|
|
|
|
|
5. API descifra con clave privada
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Generación de Claves
|
|
|
|
|
|
|
|
|
|
Las claves RSA se generan automáticamente en `./keys/`:
|
|
|
|
|
- `private.pem`: Clave privada (nunca expuesta)
|
|
|
|
|
- `public.pem`: Clave pública
|
|
|
|
|
|
|
|
|
|
## HTTPS
|
|
|
|
|
|
|
|
|
|
**Importante**: En producción, la API debe usar HTTPS.
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
# config.yml
|
|
|
|
|
server:
|
|
|
|
|
port: 443
|
|
|
|
|
cert: ./ssl/server.crt
|
|
|
|
|
key: ./ssl/server.key
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Variables de Entorno
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
VERIFACTU_ENV=test # test o production
|
|
|
|
|
VERIFACTU_CERT_PATH=... # path al certificado
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Rate Limiting
|
|
|
|
|
|
|
|
|
|
No implementado actualmente, pero recomendado para producción.
|
|
|
|
|
|
|
|
|
|
## Logs
|
|
|
|
|
|
|
|
|
|
Los logs contienen:
|
|
|
|
|
- Requests recibidos
|
|
|
|
|
- Errores de validación
|
|
|
|
|
- Respuestas de AEAT (sin información sensible)
|
|
|
|
|
|
|
|
|
|
No contienen:
|
|
|
|
|
- Contraseñas
|
|
|
|
|
- Tokens
|
|
|
|
|
- Contenido de certificados
|