Verificar un informe
Cada informe en PDF que emitimos va firmado criptográficamente. Cualquiera —tú, tu cliente, la otra parte de una negociación— puede comprobar que un informe salió de nosotros y que nadie lo ha tocado por el camino, sin pedirnos permiso y sin tener cuenta.
Lo más rápido es la página. En uttera.ai/verificar se
sube el PDF y ya está: no hay nada que copiar ni que pegar, porque la firma viaja dentro
del propio fichero. Sirve para quien recibe un informe y no va a escribir código —un
abogado, un perito, la otra parte—. El resto de este capítulo es para hacerlo por tu
cuenta, con curl o sin pasar por nosotros.
🔴 Autenticidad no es veracidad. Verificar un informe dice de dónde viene el documento y que nadie lo ha modificado. No dice que lo que cuenta sea cierto. El informe se genera a partir de una grabación que aporta el cliente, y tanto la exactitud de la transcripción como la veracidad de lo que en ella se dice son responsabilidad suya. Uttera no presencia lo grabado, no lo comprueba y no lo certifica.
Qué es y qué no es. Es una firma criptográfica de autenticidad con Ed25519. No es una firma electrónica cualificada en el sentido del reglamento eIDAS: prueba que el documento salió de nuestro sistema y que no ha cambiado, no equivale a un certificado de un prestador cualificado. Lo decimos aquí y lo dice el propio informe.
Por qué son dos firmas
Cada informe lleva dos, y cada una responde a una pregunta distinta:
| Firma | Sobre qué | Qué responde |
|---|---|---|
| de contenido | lo que el informe dice: resumen, transcripción, nombre del cliente, fecha y consumo | «¿este texto salió de Uttera?» — sigue valiendo aunque el PDF se haya reimprimido, recortado o vuelto a guardar |
| de contenedor | los bytes del fichero PDF | «¿este fichero es exactamente el que se emitió?» — detecta un solo byte cambiado |
La de contenido va impresa dentro del informe, al pie de cada página, en forma de
huella corta. La de contenedor no puede ir dentro —firmar algo que luego se modifica
es imposible— así que se añade detrás del documento ya terminado, en una línea al
final del fichero que empieza por %%UTTERA-FIRMA-V1:. Un lector de PDF no la
ve: el formato manda leer desde el último startxref, así que lo que va después
del %%EOF lo ignora.
Esto es lo que permite que baste con el PDF para comprobar las dos firmas. Antes
la devolvía la API aparte y había que guardarla al lado del fichero: en cuanto alguien
reenviaba el informe por correo, la firma se quedaba atrás y el documento era imposible de
verificar. La API la sigue devolviendo en report.container_signature para quien
prefiera archivarla por separado.
La clave pública
La publicamos en tres sitios, y los tres dan lo mismo:
https://uttera.ai/.well-known/uttera-firma.pub el PEM, a secas
https://uttera.ai/.well-known/uttera-firma.json todas las claves, con sus fechas
https://api.uttera.ai/v1/reports/public-key la que está firmando ahora
La cadena de confianza es la misma que usan DKIM o los conjuntos de claves JWKS: el
certificado TLS de uttera.ai acredita que el dominio es nuestro, y ese dominio
publica la clave. No hace falta que te fíes de nosotros por teléfono.
Comprobarlo desde la línea de órdenes
El endpoint es público y no lleva clave de API:
POST https://api.uttera.ai/v1/reports/verify
Con el PDF y nada más. Es el modo normal: la firma va dentro del fichero, así que no hace falta nada que hayas tenido que guardar aparte. Comprueba las dos firmas de una vez:
curl -s -X POST https://api.uttera.ai/v1/reports/verify \
-H "Content-Type: application/json" \
-d "{\"modo\":\"pdf\",\"pdf_b64\":\"$(base64 -w0 informe.pdf)\"}"
{"mode": "pdf", "signed": true,
"valid_container": true, "valid_content": true,
"key_fingerprint": "56ac333b…",
"fields": {"cliente": "…", "titulo": "…", "generado": "1789641036", …}}
Las dos a true es el caso bueno. valid_content a
true con valid_container a false quiere decir que
el texto es el nuestro pero el fichero se ha vuelto a guardar —cualquier herramienta
de PDF que lo abra y lo escriba cambia los bytes—, que no es lo mismo que una
falsificación. signed a false es que el fichero no lleva firma
nuestra, o que se la han quitado.
Los dos modos que siguen son para cuando tienes las piezas sueltas: un informe antiguo, o la firma archivada aparte.
Comprobar el fichero (firma de contenedor). Necesitas el PDF y la firma que vino
con él en report.container_signature:
curl -s -X POST https://api.uttera.ai/v1/reports/verify \
-H "Content-Type: application/json" \
-d "{\"modo\":\"contenedor\",
\"pdf_b64\":\"$(base64 -w0 informe.pdf)\",
\"firma_b64\":\"LA_FIRMA_DE_CONTENEDOR\"}"
{"valid": true, "mode": "contenedor", "key_fingerprint": "56ac333b…"}
Comprobar el contenido. Necesitas la respuesta del análisis tal cual te la
devolvimos, más report.content_signature y la fecha de
report.generated_unix — el sello unix, que es el valor que se firmó; generated_at es la fecha escrita, para leer. El sello va impreso en el propio informe, junto al número:
curl -s -X POST https://api.uttera.ai/v1/reports/verify \
-H "Content-Type: application/json" \
-d '{"modo":"contenido",
"datos": { …la respuesta de /v1/summarize… },
"cliente":"Meridiano Asesores, S.L.",
"titulo":"Acta de la reunión",
"generado":1789639533,
"firma_b64":"LA_FIRMA_DE_CONTENIDO"}'
No guardamos nada para esto. Verificar es una operación de clave pública sobre lo que nos mandas: no consultamos ningún registro. Por eso funciona con un informe de hace años, y por eso no podemos decirte cuántos informes hemos emitido ni buscarte uno que hayas perdido.
Rotación de claves
Cada clave se usa doce meses, y se cambia antes si hay cualquier sospecha. Las claves retiradas se quedan publicadas para siempre: un informe firmado hoy tiene que poder verificarse dentro de diez años.
Por eso cada informe lleva impresa, además de su firma, la huella de la clave que lo firmó. El verificador sabe cuál usar sin tener que probarlas todas.
Si alguna vez tuviéramos que retirar una clave por compromiso, lo diríamos aquí con la fecha. Y diríamos también lo incómodo: los informes firmados con ella dejan de probar nada, porque quien tuviera la clave podría haber firmado documentos con fecha anterior.