Flujo de Firma Digital¶
¿Cómo se firma un documento?¶
El proceso de firma digital implica varios pasos coordinados entre tu aplicación, la API REST y el motor de firma.
Paso a Paso¶
1. Autentícate¶
Primero, obtén tus tokens de acceso:
Recibirás: - jwtToken - Usa este token en el header Authorization - refreshToken - Guárdalo para renovar después
2. Inicia un grupo de firma¶
Un grupo de firma es un contenedor que agrupa documentos para procesarlos juntos.
POST /api/v2/grupo-proceso-firma/iniciar-grupo
{
"idFirmante": "12345678",
"idProceso": 1,
"documentos": [
{
"nombre": "contrato.pdf",
"codigo": "CTR001",
"contenido": "<base64_del_pdf>"
}
]
}
Recibirás: - gruProFirId - ID del grupo (guarda este número)
3. Genera los hashes¶
El motor de firma necesita hashes (resúmenes) de los documentos para poder firmarlos.
POST /api/v2/ssigner/generar-hash
{
"idGP": "123",
"idFirmante": "12345678",
"certifcadoPublicoFirmante": "<base64_del_certificado>",
"userMotivo": "Firma de contrato",
"userLocacion": "Lima, Peru"
}
Recibirás: - hashes - Lista de hashes que debes firmar - algoritmo - Algoritmo usado (normalmente SHA256)
4. Firma los hashes (en tu dispositivo)¶
Este paso es crítico: los hashes se firman localmente en tu computadora usando tu certificado digital.
Lo que debes hacer: 1. Recibes el hash en Base64 2. Usas tu certificado (desde Windows, token USB, o archivo P12) 3. Firmas el hash con tu clave privada 4. Obtienes el hash firmado (también en Base64)
Esto garantiza que tu clave privada nunca sale de tu dispositivo.
5. Envía los hashes firmados¶
Una vez que tienes los hashes firmados, envíalos a la API:
POST /api/v2/ssigner/insertar-hash-firmado
{
"idpg": 123,
"hashesFirmados": ["<hash_firmado_base64>"]
}
El motor de firma combina los hashes firmados con los documentos originales y genera los PDF finales.
6. Verifica y descarga¶
Confirma que todo salió bien:
Cuando readyToDownload sea true, puedes descargar los documentos:
Estados del Grupo de Firma¶
El grupo pasa por diferentes estados mientras avanza el proceso:
| Estado | Valor | Significado |
|---|---|---|
| INITIATED | 1 | Grupo creado, esperando hashes |
| DICHARGED | 2 | Hashes generados, esperando firma |
| CONFIGGETTER | 3 | Configuración recuperada |
| UPLOADED | 4 | Hashes firmados recibidos |
| FINALIZED | 5 | Proceso completado |
| CANCELLED | 0 | Grupo cancelado |
Diagrama del Flujo¶
┌────────┐ ┌─────────┐ ┌─────────┐ ┌──────────┐
│ Tu │ │ API │ │ Motor │ │ Archivos │
│ App │ │ REST │ │ SSigner │ │ (FS) │
└───┬────┘ └────┬────┘ └────┬────┘ └────┬─────┘
│ │ │ │
│ 1. Auth │ │ │
├───────────────>│ │ │
│<───────────────│ │ │
│ jwtToken │ │ │
│ │ │ │
│ 2. Iniciar │ │ │
├───────────────>│ │ │
│ │──────> guardar entrada/ │
│<───────────────│ │ │
│ gruProFirId │ │ │
│ │ │ │
│ 3. Generar │ │ │
│ hash │ │ │
├───────────────>│──> generar .prefirma │
│ │ │───────────────>│
│<───────────────│ │ │
│ hashes[] │ │ │
│ │ │ │
│ 4. Firmar │ (en tu │ │
│ local │ computadora)│ │
│ │ │ │
│ 5. Insertar │ │ │
│ hash firm. │ │ │
├───────────────>│──> ihf ─────>│ │
│ │ │───────────────>│
│<───────────────│ │ │
│ ok │ │ │
│ │ │ │
│ 6. Verificar │ │ │
├───────────────>│ │ │
│<───────────────│ │ │
│ docs firmados│ │ │
│ │ │ │
│ Descargar │ │ │
├───────────────>│<──────────────│ │
│<───────────────│ │ │
│ PDF final │ │ │
Ejemplo Completo con cURL¶
#!/bin/bash
API="http://localhost:8087"
EMAIL="admin@empresa.com"
PASS="MiPass123"
# 1. Autenticarse
TOKEN=$(curl -s -X POST $API/auth/acceder \
-H "Content-Type: application/json" \
-d "{\"email\":\"$EMAIL\",\"password\":\"$PASS\"}" \
| jq -r '.jwtToken')
echo "Token obtenido"
# 2. Iniciar grupo
GRP=$(curl -s -X POST $API/api/v2/grupo-proceso-firma/iniciar-grupo \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"idFirmante": "12345678",
"idProceso": 1,
"documentos": [
{"nombre": "doc.pdf", "codigo": "D1", "contenido": "'$(base64 doc.pdf)'"}
]
}')
GRP_ID=$(echo $GRP | jq -r '.gruProFirId')
echo "Grupo creado: $GRP_ID"
# 3. Generar hash
HASH_RESP=$(curl -s -X POST $API/api/v2/ssigner/generar-hash \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"idGP\": \"$GRP_ID\",
\"idFirmante\": \"12345678\",
\"certifcadoPublicoFirmante\": \"$(base64 cert.pem)\"
}")
HASH=$(echo $HASH_RESP | jq -r '.hashes[0]')
echo "Hash generado"
# 4. En tu app, firmas el hash con el certificado...
# 5. Insertar hash firmado
curl -s -X POST $API/api/v2/ssigner/insertar-hash-firmado \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"idpg\": $GRP_ID, \"hashesFirmados\": [\"$HASH_FIRMADO\"]}"
echo "Hash insertado"
# 6. Descargar
curl -s -X GET $API/api/v2/documento/descargar-firmado-blob/1 \
-H "Authorization: Bearer $TOKEN" \
-o documento_firmado.pdf
echo "Documento guardado"
Notas Importantes¶
- Tu clave privada nunca sale de tu dispositivo: Los hashes se firman localmente
- Un grupo puede contener múltiples documentos: Se procesan todos juntos
- Los documentos permanecen en el servidor: Solo viajan los hashes, no los PDFs
- El grupo tiene estados: Si algo falla, puedes identificar en qué paso ocurrió
¿Qué hacer si algo falla?¶
| Problema | Posible causa |
|---|---|
| Error 401 | Token expirado o inválido. Renueva con /auth/refrescar |
| Error 404 en grupo | El grupo no existe o fue cancelado |
| Hash no coincide | El documento fue modificado después de generar el hash |
| Certificado inválido | Revisa la fecha de vencimiento del certificado |