Retenez un point que vous pouvez vérifier : la première ouverture de la page de lecture ne doit charger que le cadre de la page. Elle ne doit pas encore récupérer le texte chiffré. Après un clic sur Ouvrir et voir, Network doit montrer une requête par identifiant. Après une récupération réussie qui épuise le compteur, le même identifiant doit renvoyer 410. La barre d’adresse peut encore porter la clé derrière #. Cette même chaîne ne doit pas apparaître sur la ligne de requête.
Que le lien existe encore ne dit rien sur le chiffré
On entend « auto-destructible » et l’on imagine le lien bleu prendre feu. La métaphore pointe souvent le mauvais objet. Un client de chat n’efface pas un message parce que la destination a répondu 410. L’historique du navigateur, l’e-mail d’origine et le commentaire du ticket restent. Ce qui brûle, c’est le texte chiffré de courte durée chez l’hébergeur. L’URL complète, dans une main, reste une chaîne de caractères. Rouvrez-la : l’identifiant pointe vers un objet qui n’est plus là.
Séparez deux éléments avant de demander ce qui reste. L’un est le localisateur : l’identifiant après le point d’interrogation, qui dit au serveur quel enregistrement récupérer. L’autre est la clé de déchiffrement : le fragment après le dièse, qui reste dans l’onglet courant. L’hébergeur est conçu pour voir le premier et ne jamais voir le second. Après une lecture réussie, le localisateur peut encore nommer une case vide. Si la clé traîne encore dans l’historique du chat, elle ne déchiffre plus rien : le texte chiffré a disparu.
Un lien de partage de fichiers fonctionne à l’envers. Tant que ce lien est valable, le fichier est en général encore sur le disque. Vous révoquez un accès ; vous ne supprimez pas l’objet à la première ouverture. Un secret à usage unique lie « lire » et « supprimer » à la même récupération. À la création, vous fixez un nombre de lectures (1–10, 1 par défaut) et une expiration (1 heure, 24 heures, 7 jours, ou destruction après lecture seulement). Le chemin par défaut : première récupération réussie, le texte chiffré est supprimé. Non lu et expiré : même suppression. Aucune des deux voies ne laisse une copie en clair à récupérer plus tard.
Le serveur n’a jamais détenu le texte en clair
« Supprimer le clair après la première lecture » est l’autre lecture inversée. L’ordre réel : le clair n’existe que dans l’onglet de l’expéditeur ; le navigateur tire une clé aléatoire de 256 bits avec Web Crypto et chiffre en AES-256-GCM ; les champs sortants sont le texte chiffré, l’expiration et le nombre maximal de lectures. Le serveur renvoie un identifiant imprévisible. La page accroche ensuite la clé à s.html?id={id}#{clé}. Il n’y a pas d’étape qui écrit d’abord la phrase secrète dans une base pour la chiffrer ensuite.
Les paramètres se contrôlent, ce n’est pas un slogan. NIST SP 800-38D recommande un IV de 96 bits (12 octets) pour GCM, afin que les implémentations restent interopérables et simples ; l’étiquette d’authentification fait souvent 128 bits (16 octets). AesGcmParams de Web Crypto a cette forme. Chez MakePwd, le texte chiffré est le Base64 de IV 12 octets + chiffré + étiquette 16 octets. La clé fait 32 octets. Chaque élément est plafonné à 32 Ko. Ces chiffres figurent sur la page de création. Vous pouvez aussi inspecter un lien que vous venez de générer : ce qui suit le dièse est la clé en Base64URL, pas la phrase que vous avez tapée.
GCM donne aussi l’intégrité. Si le chiffré ou l’étiquette est altéré, le déchiffrement échoue dans cet onglet. Vous n’obtenez pas un clair « à peu près ». Cela bloque une altération en transit. Cela ne bloque pas une capture d’écran une fois que quelqu’un a déjà lu le message. Le serveur n’a jamais la clé : il ne peut pas déchiffrer à votre place, ni scanner le corps, ni fabriquer une copie en clair après lecture. Ce qu’il peut faire : remettre le texte chiffré selon l’identifiant, puis le supprimer selon le compteur ou le TTL.
| Étape | Dans le navigateur | Sur le serveur |
|---|---|---|
| Création terminée | Le clair que vous venez de saisir, plus le lien complet | Texte chiffré, identifiant, TTL, lectures restantes |
| Premier rendu de la lecture | Identifiant et clé # dans la barre d’adresse |
Toujours le chiffré ; ce rendu ne l’a pas supprimé |
| Confirmation réussie | Clair déchiffré dans cet onglet | Supprimé si le compteur est épuisé ; sinon décrémenté |
| Même identifiant rouvert | La clé peut encore être dans la barre d’adresse | Détruit ou expiré ; une réponse de classe 410 |
L’identifiant dans la query, la clé derrière le dièse
Un lien à usage unique doit faire deux métiers : dire au serveur quel enregistrement récupérer, et dire au navigateur du destinataire quelle clé utiliser. Ces métiers ne doivent pas partager le même champ HTTP. La query après ? s’écrit dans la ligne de requête : les reverse proxies et les journaux d’accès sont conçus pour la voir. Le fragment après # est laissé au client.
La RFC 9110, section 7.1 est explicite : l’URI cible exclut le fragment, parce que les identifiants de fragment sont traités par le client. Le navigateur demande au serveur s.html?id=…, pas toute la barre d’adresse. Déplacez la clé vers ?key= et « chiffré seulement » est déjà faux au niveau des logs : un opérateur qui ouvre le journal d’accès du jour a la seconde moitié nécessaire pour déchiffrer.
La note précédente a déjà déroulé cette couche. La frontière ici est courte : la séparation empêche l’hébergeur de voir la clé. Elle ne rend pas la chaîne complète sûre à transférer. Collez une URL qui contient encore # dans un chat, et le destinataire comme l’éditeur du chat voient la clé. Un fragment bloque HTTP. Il ne bloque pas le presse-papiers. Les contrôles à faire dans Network sont dans Pourquoi le fragment après # d’une URL convient pour une clé, et quand cette protection lâche.
La destruction a lieu à la récupération du chiffré, pas au premier rendu
Ouvrir la page de lecture et consommer une lecture ne sont pas le même événement. Le HTML de lecture peut d’abord se dessiner : vérifier que l’adresse a un ?id= et une clé #, puis s’arrêter sur un bouton de confirmation. Cette étape ne coûte que des ressources statiques. La requête qui dit au serveur de supprimer le texte chiffré est la récupération ultérieure par identifiant. Après le clic, la récupération réussit, le compteur est épuisé : l’enregistrement passe de « encore récupérable » à « détruit ».
Une clé manquante ne doit pas déclencher de récupération. Si l’adresse n’a qu’un identifiant — parce qu’un client de chat a coupé le hash — la page de lecture doit dire que le fragment manque, pas demander d’abord le texte chiffré au serveur. Sinon vous dépensez la seule lecture : le serveur remet le chiffré et le supprime, le navigateur ne peut pas déchiffrer, et l’expéditeur croit que l’autre personne a déjà lu. Le comportement vérifiable : sans #, Network ne doit pas montrer l’API de texte chiffré ; avec un lien complet et un clic de confirmation, elle doit apparaître.
Le compteur n’est pas toujours 1. La création peut fixer 1 à 10. Mettez 3 : après les deux premières récupérations réussies, le texte chiffré est encore sur le serveur ; seul le reste a baissé. Le troisième succès le supprime. La valeur 1 par défaut correspond à « transmettre un mot de passe une fois », pas à un protocole qui ne peut se lire qu’une fois. Le TTL est une condition de suppression séparée : non lu après 24 heures, le chiffré disparaît aussi, et l’état doit pouvoir se distinguer de « quelqu’un l’a déjà lu ». La page de lecture MakePwd traite expired dans une réponse 410 comme une expiration ; les autres états détruits sont traités comme déjà brûlés.
Ne testez pas avec un vrai mot de passe, une clé API de production ou une chaîne de connexion non masquée. Utilisez un canari jetable, par exemple canary-burn-2026-do-not-reuse. Vous contrôlez des codes de statut et la ligne de requête, vous ne rediffusez pas un secret.
410 et 404 : détruit, expiré, ou jamais là
Une fois le texte chiffré parti, le serveur doit encore répondre à la requête suivante. La RFC 9110, section 15.5.11 décrit 410 Gone ainsi : la ressource cible n’est plus disponible sur le serveur d’origine, et cet état est probablement permanent. Si l’origine ne peut pas dire si c’est permanent, elle doit plutôt renvoyer 404. La note MDN sur le 410 ajoute que les clients ne doivent pas continuer à réessayer, et que le site doit retirer les liens qui pointent encore vers la ressource.
Pour un secret à usage unique, le 410 convient mieux que le 404 : cet identifiant a un jour nommé un objet chiffré, puis cet objet a été supprimé volontairement, et il ne reviendra pas. Expiration et compteur épuisé peuvent tous deux renvoyer 410, le corps de réponse séparant expired d’une destruction normale pour que le destinataire ne croie pas avoir mal tapé le lien. Un 404 peut encore apparaître — identifiant invalide, ou enregistrement effacé si complètement que l’hébergeur ne prétend plus qu’il ait jamais existé. Pour l’expéditeur, les deux réponses disent la même chose : n’attendez pas que l’hébergeur vous rende le contenu.
Le 410 dit aussi aux robots d’indexation de cesser de revenir. La page de lecture est une page d’arrivée temporaire de texte chiffré. Elle doit être noindex pour les moteurs et ne doit pas entrer dans un sitemap. On ne veut pas qu’une page de mot de passe à usage unique soit indexée. La page de création peut l’être, parce qu’elle explique comment générer un lien. La page de lecture ne sert que les personnes qui tiennent déjà l’URL complète.
Pourquoi l’aperçu d’un chat peut consommer la seule lecture
L’accident habituel n’est pas un cryptographe qui casse AES. C’est un robot d’aperçu plus rapide qu’un collègue. Vous collez l’URL complète dans un chat. Le client interroge cette adresse pour afficher une carte d’aperçu. La documentation Slack sur le dépliage de liens le dit clairement : par défaut, lorsqu’un lien apparaît dans un message, Slack le récupère et propose un aperçu. Teams, Discord et certains scanners de messagerie font une récupération voisine. Ils veulent un titre et un résumé, pas votre mot de passe. Si « le premier GET récupère aussi le texte chiffré et le supprime », cette visite consomme la seule lecture. Le collègue ouvre une page déjà détruite.
Une clé derrière # est une couche contre cette récupération côté serveur : le robot demande s.html?id=…, et le fragment n’est pas envoyé avec HTTP. L’aperçu ne peut en général pas déchiffrer, donc la carte n’affiche pas la phrase secrète. Ce qu’il peut brûler, c’est le compteur de lectures, pas la clé elle-même. Si votre page de lecture récupère le texte chiffré au chargement, l’aperçu équivaut à cliquer Ouvrir et voir à la place du destinataire. Il obtient un 410. Vous croyez qu’il a déjà lu.
La mesure réaliste n’est pas « ne jamais coller de lien ». C’est de séparer « afficher la page » et « récupérer le texte chiffré ». La lecture affiche d’abord une confirmation et dit que ce clic consommera une lecture ; seulement ensuite elle envoie la récupération. Un aperçu qui prend le HTML et ne clique pas le bouton s’arrête à la confirmation. Cela n’arrête pas un scanner qui exécute le script complet et simule un clic, et cela n’arrête pas une personne qui clique la mauvaise carte. Cela fait passer l’échec courant « la carte l’a ouvert une fois » du cas par défaut à un lien qui survit.
Une seconde habitude aide dans les salons qui déplient automatiquement : envoyer « le mot de passe passe par un lien auto-destructible ; URL dans un message à part », ou mettre la chaîne complète dans un message privé sans aperçu. L’URL complète reste un jeton au porteur. L’aperçu ne fait que consommer un compteur. Il ne change pas « quiconque a la chaîne entière peut déchiffrer ».
Contrôler sur place : s’arrêter à la confirmation, puis chercher dans Network
« Détruit après lecture » et « zéro connaissance » ne se prouvent pas tout seuls. Quatre choses que vous pouvez voir : si la création a envoyé du clair ; si le premier chargement de lecture a récupéré le texte chiffré ; si la ligne de requête de confirmation contient la clé ; et si une seconde ouverture après un compteur épuisé est un 410.
Préparez d’abord un canari. Ouvrez la page de création du lien auto-destructible, tapez une phrase jetable, mettez le TTL à 1 heure et laissez les lectures à 1. N’envoyez le résultat à personne. Regardez la séparation dans le volet de résultat : côté query, l’identifiant seulement ; côté fragment, la clé. Puis ouvrez Network dans les outils de développement, activez Preserve log, et cherchez le canari en entier. Le corps de création doit être du texte chiffré, pas cette phrase. L’analyse ne doit pas non plus porter la phrase.
- Ouvrez la page de lecture avec le même lien complet. Ne cliquez pas encore sur la confirmation. Network ne doit montrer que le document et les ressources statiques — pas une récupération de texte chiffré par identifiant.
- Comparez la barre d’adresse et la ligne de requête du document. La barre d’adresse garde
#et ce qui suit. La ligne de requête ne doit montrer que le chemin et?id=. - Cliquez sur la confirmation. La récupération du texte chiffré doit apparaître maintenant. Après succès, la page affiche le clair. Rouvrez le même lien. Vous devez atterrir sur détruit ou 410, pas sur le même canari.
Trois passages propres ne soutiennent qu’une affirmation étroite : dans ce navigateur, sur cette exécution, le clair n’est pas parti comme champ métier observé, la clé n’est pas entrée dans la ligne de requête, et le texte chiffré n’était plus récupérable après une lecture réussie. Cela ne prouve pas qu’une extension n’a jamais lu le champ, et cela ne prouve pas qu’un disque compromis n’a jamais détenu d’ancien chiffré. Changez de navigateur, et il vaut la peine de relancer le canari. S’il faut aussi vérifier si du clair a quitté une page d’outil, les étapes sont dans Chiffrer dans le navigateur : comment vérifier que le texte en clair n’a pas quitté l’appareil.
Cela n’empêche ni copie, ni capture, ni transfert du lien complet
Un lien auto-destructible réduit deux risques : le clair qui resterait longtemps sur le serveur, et le même texte chiffré ouvert encore et encore. Il ne réduit pas un troisième : ce que le destinataire fait une fois qu’il voit le clair. Il peut copier, capturer, transférer, ou lire à voix haute. Le lien lui-même peut être transféré en entier — clé et identifiant voyagent ensemble — et la personne suivante peut déchiffrer sur la page de lecture tant qu’il reste une lecture.
C’est aussi pourquoi « le destinataire doit se connecter » ne règle pas la remise. Le contrôle d’accès, c’est l’URL complète. Mettre une porte de compte sur la lecture n’empêche pas le serveur de voir la clé — la clé ne doit jamais lui être envoyée. Cela n’ajoute qu’une porte pour le destinataire et transforme « qui tient le lien » en « qui a un compte ». MakePwd n’a ni compte ni coffre de mots de passe. Création et lecture s’ouvrent sans inscription. La page de lecture est publique pour le destinataire.
La capacité a aussi une frontière. 32 Ko suffisent pour une phrase secrète, une clé API, un code de récupération et une courte note. Ce n’est pas assez pour un dump de base ou un paquet de certificats entier. Un fichier entier doit devenir .lock / .enc sur cet appareil et voyager par un disque ou un e-mail. Le chiffrement de fichiers accepte un fichier jusqu’à 5 Go, aussi sans compte, et n’envoie pas le clair par défaut. Faire passer un gros fichier par un canal de texte à usage unique n’est pas « plus sûr ». C’est hors de ce pour quoi ce chemin est construit.
S’exercer à l’état détruit sur une page de création sans compte
Si vous voulez un outil qui écrit la séparation query / fragment dans le volet de résultat, commencez par le lien auto-destructible de MakePwd. Il s’ouvre sans inscription des deux côtés. Le chiffrement à la création se fait dans l’onglet courant avec AES-256-GCM. Le serveur reçoit le texte chiffré, ttl_hours (0–168, 24 par défaut) et max_reads (1–10, 1 par défaut). Le lien généré a toujours la forme s.html?id={id}#{clé}. La page de lecture s’arrête à la confirmation, puis récupère le texte chiffré et déchiffre dans cet onglet.
Utilisez le canari ci-dessus et laissez les lectures à 1. Regardez trois endroits à la fois : la séparation query / fragment à la création, si Network récupère le texte chiffré au premier chargement de lecture, et si la seconde ouverture est détruite. La séparation confirme que la clé n’est pas entrée dans la query. Le premier chargement confirme qu’un aperçu ne brûlera pas par accident. La seconde ouverture confirme que « détruit après lecture » n’est pas une formule.
Si le contenu doit encore perdre des paramètres de suivi avant tout autre envoi, passez d’abord par Supprimer les UTM, puis placez la courte chaîne qui doit vraiment rester secrète dans le lien auto-destructible. Le nettoyage retire UTM et identifiants de clic d’une query. Il ne remplace pas un canal de texte chiffré à usage unique. Aucune de ces étapes n’exige de compte, et aucune n’affiche une boîte mail d’assistance qui n’est pas branchée.
Questions fréquentes
Après une ouverture, le texte en clair reste-t-il sur le serveur ?
Le clair n’y a jamais été. Le navigateur chiffre d’abord. Le serveur ne reçoit que le texte chiffré. Après une récupération réussie qui épuise le compteur, le chiffré est supprimé. Une requête ultérieure pour le même identifiant doit voir un 410 ou un état détruit. La chaîne d’URL peut encore traîner dans l’historique du chat. Ce n’est pas une copie en clair chez l’hébergeur.
L’aperçu d’un chat détruira-t-il le secret d’abord ?
Il peut consommer le compteur. Il ne peut en général pas brûler le clair. L’aperçu récupère la page ; la clé derrière # n’entre pas dans HTTP. Si la lecture récupère le texte chiffré au chargement, l’aperçu dépense la seule lecture. La bonne implémentation confirme d’abord, puis récupère. Slack et des produits voisins récupèrent par défaut les liens d’un message pour afficher une carte d’aperçu.
Quelle différence entre 410 et 404 ?
410 signifie que la ressource était disponible et a été retirée pour de bon ; les clients ne doivent pas réessayer. 404 est plus flou : l’identifiant peut être invalide, ou l’enregistrement déjà effacé. Un secret à usage unique est plus clair quand le 410 sépare détruit et expiré. Dans les deux cas, il n’y a pas de clair à restaurer.
Faut-il un compte pour ouvrir la page de lecture ?
Non. Création et lecture s’ouvrent sans compte. Le destinataire récupère le texte chiffré avec l’identifiant et déchiffre dans cet onglet avec la clé derrière le dièse. MakePwd n’a ni compte ni coffre de mots de passe. Le contrôle d’accès, c’est le lien complet lui-même.
Trois points à retenir avant le prochain secret à usage unique
Premier : quand vous demandez « que reste-t-il après une lecture », demandez d’abord si du clair a jamais été sur le serveur. Non. Ce qui est supprimé, c’est le texte chiffré. Une URL encore dans le chat ne déchiffre plus rien. Deuxième : le point de destruction est la récupération du chiffré, pas le premier rendu de la lecture. Le bouton de confirmation est là pour les robots d’aperçu, pas pour quelqu’un qui a déjà la chaîne entière. Troisième : contrôlez Network : cherchez le canari à la création, comparez la ligne de requête et # à la lecture, et cherchez un 410 à la seconde ouverture.
S’il vous reste à comprendre pourquoi une clé peut rester derrière le dièse, lisez Pourquoi le fragment après # d’une URL convient pour une clé, et quand cette protection lâche. Cette note ne fait que transformer « que reste-t-il sur le serveur après une lecture » en un périmètre que vous pouvez confronter à des codes de statut et au moment des requêtes.