Vérifier un rapport
Chaque rapport PDF que nous émettons est signé cryptographiquement. N'importe qui —vous, votre client, l'autre partie d'une négociation— peut vérifier qu'un rapport vient de nous et que personne n'y a touché en chemin, sans nous demander la permission et sans compte.
Le plus rapide est la page. Sur uttera.ai/fr/verify, vous téléversez le PDF et c'est tout : il n'y a rien à copier ou coller, parce que la signature voyage à l'intérieur du fichier lui-même. C'est prévu pour quiconque reçoit un rapport et ne va pas écrire de code — un avocat, un expert, la partie adverse. Le reste de ce chapitre est pour le faire vous-même, avec curl ou sans passer par nous.
🔴 L'authenticité n'est pas la vérité. Vérifier un rapport vous dit d'où vient le document et que personne ne l'a modifié. Cela ne dit pas que ce qu'il dit est vrai. Le rapport est généré à partir d'un enregistrement fourni par le client, et tant l'exactitude de la transcription que la véracité de ce qui y est dit sont de sa responsabilité. Uttera n'a pas été témoin de ce qui a été enregistré, ne le vérifie pas et ne le certifie pas.
Ce que c'est et ce que ce n'est pas. C'est une signature d'authenticité cryptographique utilisant Ed25519. Ce n'est pas une signature électronique qualifiée au sens du règlement eIDAS : elle prouve que le document est sorti de notre système et n'a pas changé, elle n'est pas l'équivalent d'un certificat d'un prestataire qualifié. Nous le disons ici, et le rapport le dit aussi.
Pourquoi il y a deux signatures
Chaque rapport en porte deux, et chacune répond à une question différente :
| Signature | Sur quoi | Ce à quoi elle répond |
|---|---|---|
| contenu | ce que le rapport dit : résumé, transcription, nom du client, date et consommation | « ce texte vient-il d'Uttera ? » — elle tient toujours si le PDF a été réimprimé, rogné ou réenregistré |
| conteneur | les octets du fichier PDF | « ce fichier est-il exactement celui qui a été émis ? » — elle détecte un seul octet changé |
Celle du contenu est imprimée à l'intérieur du rapport, dans le pied de chaque page, comme une courte empreinte. Celle du conteneur ne peut pas aller à l'intérieur —signer quelque chose qui est ensuite modifié est impossible— elle est donc ajoutée après le document fini, sur une ligne à la fin du fichier commençant par %%UTTERA-FIRMA-V1:. Un lecteur de PDF ne la voit jamais : le format dit de lire à partir du dernier startxref, donc tout ce qui suit le %%EOF est ignoré.
C'est ce qui fait que le PDF seul suffit pour vérifier les deux signatures. Auparavant, elle était renvoyée séparément par l'API et il fallait la garder à côté du fichier : dès que quelqu'un transférait le rapport par e-mail, la signature restait en arrière et le document ne pouvait plus être vérifié du tout. L'API la renvoie toujours dans report.container_signature pour quiconque préfère l'archiver séparément.
La clé publique
Nous la publions à trois endroits, et les trois donnent la même chose :
https://uttera.ai/.well-known/uttera-firma.pub le PEM, seul
https://uttera.ai/.well-known/uttera-firma.json chaque clé, avec ses dates
https://api.uttera.ai/v1/reports/public-key celle qui signe en ce moment
La chaîne de confiance est la même qu'utilisent les jeux de clés DKIM ou JWKS : le certificat TLS d'uttera.ai atteste que le domaine est le nôtre, et ce domaine publie la clé. Vous n'avez pas à nous croire sur parole au téléphone.
Le vérifier depuis la ligne de commande
Le endpoint est public et ne prend aucune clé d'API :
POST https://api.uttera.ai/v1/reports/verify
Avec le PDF et rien d'autre. C'est le mode normal : la signature est dans le fichier, donc rien que vous auriez dû garder séparément n'est nécessaire. Il vérifie les deux signatures d'un coup :
curl -s -X POST https://api.uttera.ai/v1/reports/verify \
-H "Content-Type: application/json" \
-d "{\"modo\":\"pdf\",\"pdf_b64\":\"$(base64 -w0 report.pdf)\"}"
{"mode": "pdf", "signed": true,
"valid_container": true, "valid_content": true,
"key_fingerprint": "56ac333b…",
"fields": {"cliente": "…", "titulo": "…", "generado": "1789641036", …}}
Les deux à true, c'est le bon cas. valid_content vrai avec valid_container faux signifie que le texte est le nôtre mais que le fichier a été réenregistré — tout outil PDF qui l'ouvre et l'écrit change les octets — ce qui n'est pas la même chose qu'un faux. signed faux signifie que le fichier ne porte aucune signature de nous, ou qu'elle a été retirée.
Les deux modes ci-dessous sont pour quand vous détenez les pièces séparément : un rapport plus ancien, ou une signature archivée à part.
Vérifier le fichier (signature du conteneur). Il vous faut le PDF et la signature qui l'accompagnait dans 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 report.pdf)\",
\"firma_b64\":\"THE_CONTAINER_SIGNATURE\"}"
{"valid": true, "mode": "contenedor", "key_fingerprint": "56ac333b…"}
Vérifier le contenu. Il vous faut la réponse d'analyse exactement telle que nous l'avons renvoyée, plus report.content_signature et la date de report.generated_unix — le timestamp unix, qui est la valeur qui a été signée ; generated_at est la date écrite, pour la lecture. Le timestamp est imprimé sur le rapport lui-même, à côté du numéro :
curl -s -X POST https://api.uttera.ai/v1/reports/verify \
-H "Content-Type: application/json" \
-d '{"modo":"contenido",
"datos": { …la réponse de /v1/summarize… },
"cliente":"Meridiano Asesores, S.L.",
"titulo":"Compte rendu de la réunion",
"generado":1789639533,
"firma_b64":"THE_CONTENT_SIGNATURE"}'
Nous ne stockons rien pour cela. Vérifier est une opération à clé publique sur ce que vous nous envoyez : nous ne consultons rien. C'est pourquoi cela fonctionne sur un rapport d'il y a des années, et pourquoi nous ne pouvons pas vous dire combien de rapports nous avons émis ni en retrouver un que vous avez perdu.
Rotation des clés
Chaque clé est utilisée pendant douze mois, et est remplacée plus tôt au moindre soupçon. Les clés retirées restent publiées pour toujours : un rapport signé aujourd'hui doit être vérifiable dans dix ans.
C'est pourquoi chaque rapport porte, à côté de sa signature, l'empreinte de la clé qui l'a signé. Le vérificateur sait laquelle utiliser sans les essayer toutes.
Si nous devions un jour retirer une clé parce qu'elle a été compromise, nous le dirions ici avec la date. Et nous dirions aussi la partie inconfortable : les rapports signés avec elle cessent de prouver quoi que ce soit, parce que celui qui détenait la clé aurait pu signer des documents antidatés.