Sellar un PDF con NOM-151

POST
/api/nom151/stamp

Aplica un sello de tiempo NOM-151 a un PDF que ya tienes y devuelve el archivo sellado — para documentos firmados fuera de Firmame, o PDFs ya firmados a los que hay que agregarles el sello.

Es una subida multipart/form-data con el archivo en el campo file. En multipart la cadena firmada es el SHA-256 en Base64 del archivo, que además va en el header Content-SHA256 — los SDKs se encargan de esto por ti, y también el playground.

Authorization<token>

Cada petición lleva Authorization: signmage {webId}:{firma}, donde firma es el Base64 de HMAC-SHA256(apiKey, cadenaFirmada).

Qué va dentro de cadenaFirmada depende de la petición:

PeticióncadenaFirmada
GETLa URI completa incluyendo el query string, exactamente como se envía
POST con JSONEl cuerpo JSON, re-serializado compacto (sin espacios ni salto de línea final)
POST multipartEl SHA-256 en Base64 del archivo, que además se manda en el header Content-SHA256

Dos detalles que conviene resolverlos desde el principio:

  1. En GET, la URI se firma tal como se envía, así que el orden y el encoding de los parámetros importan.
  2. En POST, la comparación se hace contra tu JSON re-serializado en forma compacta. Manda JSON compacto y canónico para que las firmas coincidan.

Una firma que no coincide devuelve 401 con el cuerpo vacío. Como la misma respuesta cubre un web ID desconocido, una llave inactiva y una firma que no coincide, revisa las tres cosas al diagnosticar.

En: header

Cuerpo de la petición

multipart/form-data

Definiciones de TypeScript

Usa el tipo request body en TypeScript.

Cuerpo de la respuesta

application/json

curl -X POST "https://example.com/api/nom151/stamp" \  -F file="string"

{  "status": "success",  "document": "JVBERi0xLjcNCiW1tbW1…",  "timestampData": {    "hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",    "tsa": "L=MIGUEL HIDALGO,ST=CIUDAD DE MEXICO,C=MX,CN=CECOBAN-PSC-NOM151-1-01,O=CECOBAN SA DE CV",    "genTime": "2021-03-30T02:34:24.582Z",    "status": "granted",    "policy": "2.16.484.101.10.316.2.3.1.2.1.1.1"  }}