Cherchez « chiffrer un fichier en ligne » ou « chiffrement côté client navigateur » : les pages répondent presque toutes la même chose. Le calcul reste ici, le fichier n’est pas envoyé, la clé ne quitte pas l’appareil. Ces phrases rassurent. Elles ne constituent pas une preuve. Une page peut les afficher pendant qu’un script envoie encore, via fetch, la phrase du formulaire, un morceau du fichier ou la clé visible dans la barre d’adresse. Ce qu’il faut vérifier n’est pas le texte marketing. C’est si cette action-là a fait sortir le texte clair du navigateur.
Cet article n’aide pas à choisir un produit, et ce n’est pas la visite guidée d’une page d’outil. La question est plus étroite : quand un site affirme chiffrer dans le navigateur, que peut-on voir tout de suite dans les outils de développement et dans la barre d’adresse ? Le chiffrement de fichier et le message autodestructif de MyPassGen s’appuient tous deux sur AES-256-GCM via la Web Crypto API, et chaque outil s’ouvre sans compte. Le même contrôle s’applique. Inutile de croire sur parole « nous ne stockons rien ».
Le slogan ne se vérifie pas. Le trafic, si
« Chiffrement côté client » est une étiquette usée. Un site envoie le fichier en POST vers son serveur, l’enveloppe en AES là-bas, puis rend un lien de téléchargement — et appelle encore cela « chiffrement en ligne ». Un autre appelle crypto.subtle.encrypt dans l’onglet, écrit un .lock ou un .enc, et n’envoie aucun dépôt métier. Les pages marketing peuvent coller la même phrase sur les deux. L’onglet Réseau, non.
Le navigateur n’audite pas le slogan. Il liste la requête document, les scripts, les images et les appels XHR / Fetch déclenchés par ce clic. On voit si l’URL de requête contient du texte clair, si le corps contient une phrase secrète, si un ping d’analytics envoie l’adresse avec la clé après #. Si ces chaînes sont absentes, « ne quitte pas cet appareil par défaut » tient encore. Si elles sont là, le slogan est déjà mort.
Inutile de lire le code source. Il faut un passage reproductible : ouvrir le panneau, faire une action concrète (générer un mot de passe, tester une phrase jetable, chiffrer un petit fichier, ou créer un lien à usage unique), puis ouvrir chaque nouvelle requête. On sépare d’abord ce que « local » nomme. Ensuite le dièse et la query. Puis les étapes.
Ce que « local » désigne vraiment
La Web Crypto API est la surface cryptographique du navigateur. crypto.subtle hache, dérive, chiffre et déchiffre. Les cas d’usage du W3C incluent une architecture licite : l’utilisateur choisit une clé dans le navigateur, chiffre un document, puis envoie les octets chiffrés à un prestataire. L’API garantit que le calcul peut avoir lieu sur cet appareil. Elle n’interdit pas d’envoyer ensuite le texte chiffré, et elle n’empêche pas un auteur d’envoyer d’abord et de chiffrer plus tard.
Web Crypto exige aussi un contexte sécurisé : HTTPS en production (localhost est l’exception habituelle). C’est une condition d’emploi, pas un argument de vente. Si une page en HTTP clair prétend « utiliser Web Crypto », regardez d’abord le cadenas dans la barre d’adresse, avant de discuter d’algorithme.
Ce qu’AES-256-GCM sur cet appareil veut dire
La première version de MyPassGen n’emploie qu’AES-256-GCM. D’après MDN AesGcmParams et la NIST SP 800-38D qu’elle cite, GCM est un chiffrement authentifié : si le texte chiffré est altéré, le déchiffrement échoue. On n’obtient pas un corps brouillé qui ressemble encore à un document. L’IV recommandé fait 96 bits — 12 octets — et il faut un IV neuf pour chaque chiffrement sous la même clé. L’IV n’est pas un secret ; il peut voyager avec le texte chiffré. L’étiquette d’authentification vaut 128 bits par défaut. Ces chiffres se vérifient dans une implémentation. Ce ne sont pas des slogans à réciter.
Le chiffrement de fichier dérive aussi une clé depuis une phrase. La page Chiffrer de ce site utilise PBKDF2, 100 000 itérations, SHA-256 et un sel de 16 octets, puis une clé AES-GCM de 256 bits. Un fichier peut aller jusqu’à 5 Go. La sortie est .lock ou .enc. Si la phrase part en POST avec le fichier, le nombre d’itérations ne sauve rien. Le premier objet à inspecter reste le trafic, pas la fonction de dérivation.
Trois « chiffrements dans le navigateur » distincts
Étalés, les flux se séparent en trois au moins. Premier : l’onglet ne fait que choisir un fichier ; les octets partent vers un serveur ; le chiffrement a lieu en face. Deuxième : l’onglet chiffre d’abord, n’envoie que le texte chiffré, et la clé voyage par un autre canal (par exemple le # de l’URL). Troisième : le résultat se télécharge ici, et aucune requête métier ne porte un corps de fichier. Les trois se vendent comme « chiffrement sur une page web ». Seuls les deux derniers peuvent dire que le texte clair n’est pas envoyé par défaut. Votre travail : classer la page sous les yeux, avec l’onglet Réseau.
Nommez l’objet avant de cliquer
Pour générer un mot de passe, tester une force, nettoyer un lien ou chiffrer un fichier, l’attente est : « le texte clair n’est pas parti comme donnée métier ». Un lien à usage unique est autre chose : un champ de texte chiffré peut apparaître, mais pas la phrase d’origine, et pas la clé après # sur la ligne de requête. Mélanger les deux attentes, et un POST de texte chiffré tout à fait normal passe pour une fuite.
Le dièse et le point d’interrogation ne sont pas le même objet
Une URL se découpe en schéma, hôte, chemin, requête (après ?) et fragment (après #). La RFC 3986 §3.5 appelle fragment ce qui suit # : c’est une position secondaire que le client interprète une fois la ressource principale arrivée. La note MDN sur le fragment d’URI est plus directe : lorsque le navigateur demande cette URI, le fragment n’est pas envoyé au serveur. Le client le traite après l’arrivée de la ressource.
La chaîne de requête fait l’inverse. À l’ouverture d’un lien https, les couples nom=valeur après ? entrent dans la ligne de requête et, en général, dans les journaux d’accès du destinataire. L’article précédent, quels paramètres d’URL supprimer avant d’envoyer un lien, traitait déjà utm_source et id= comme des noms de query. Écrire une clé en ?key=, et le serveur, le reverse proxy et les journaux CDN la voient. L’écrire après #, et la ligne de requête par défaut ne contient pas ce morceau.
Le Referer abandonne aussi le fragment. MDN Referer indique que l’en-tête peut porter l’origine, le chemin et la query. Il ne doit pas porter un fragment d’URL ni un identifiant et un mot de passe. La Referrer Policy du W3C vide de même le fragment à l’étape « strip for use as a referrer ». Donc « placer la clé après #, et la machine qui héberge le texte chiffré ne la reçoit pas par HTTP » est un comportement de protocole. Ce n’est pas une promesse de marque.
Un lien à usage unique sur ce site ressemble à s.html?id={id}#{key} : la query ne porte que l’identifiant du texte chiffré ; la clé ne vit qu’après le dièse. À la création, l’onglet fabrique une clé aléatoire de 32 octets, lance AES-256-GCM avec un IV de 12 octets, puis envoie le texte chiffré en POST. À la lecture, le script prend la clé dans location.hash et déchiffre sur cet appareil. Le texte clair est plafonné à 32 Ko. Ce qu’il faut contrôler : le JSON de création doit avoir un champ de texte chiffré et ne doit pas avoir la phrase d’origine ; la requête document de la page de lecture doit montrer id= et ne doit pas montrer le morceau après #.
Contrôle dans l’onglet Réseau
Chrome, Edge, Firefox et Safari livrent tous un panneau réseau. Les noms bougent un peu. Les étapes, non. Pas d’extension, et surtout pas de dépôt du fichier chez un « scanner » tiers : renvoyer l’URL complète ou le fichier élargit seulement l’exposition.
- Ouvrez les outils de développement et passez sur Réseau (Network). Cochez « Conserver le journal » / Preserve log, pour qu’une navigation n’efface pas la liste.
- Filtrez sur Fetch / XHR (ou « XHR »). Les ressources statiques peuvent attendre. Un envoi métier passe presque toujours par cette classe de requêtes.
- Faites l’action à contrôler : générer un mot de passe, saisir une phrase de test jetable, coller une URL encore chargée d’UTM, choisir un petit fichier à chiffrer, ou écrire un secret jetable puis créer un lien à usage unique.
- Ouvrez chaque nouvelle requête. Lisez l’URL de requête : les adresses document et API ne doivent pas contenir le texte clair que vous venez de taper, ni
#suivi de la clé. - Ouvrez Charge utile / Requête (Payload / Request). JSON ou champs de formulaire ne doivent pas porter le texte d’origine, une phrase secrète, le mot de passe testé, ni les octets bruts du fichier. Une création à usage unique peut montrer un champ de texte chiffré. Ce champ doit ressembler à du binaire aléatoire en Base64, pas à la phrase tapée.
- Parcourez les requêtes d’analytics ou de collecte (noms souvent
matomo,collectoug/collect). Voyez si l’URL de page rapportée, ou un paramètre personnalisé, a envoyélocation.hrefavec le dièse.
Le chiffrement de fichier a un contrôle plus dur : coupez le réseau ou passez en mode Avion, puis chiffrez un petit fichier. Si le calcul est censé rester ici, le téléchargement .lock / .enc doit encore aboutir. Un lien à usage unique ne passe pas ce test — il doit déposer le texte chiffré sur un serveur, donc un échec hors ligne à la création est attendu, pas un démenti. Prendre « zéro requête » comme seule note de passage, et vous éliminez à tort un lien zéro connaissance.
Une page de force de mot de passe peut charger une liste statique de mots faibles (ce site utilise leaked-top10k.txt). C’est un lexique, pas votre saisie. Dans Réseau, le fichier de liste peut apparaître. Le mot de passe de la zone de saisie ne doit pas apparaître dans la query ni dans le corps. Ce n’est pas une confrontation HIBP sur tout le web. Ce type de contrôle envoie un hachage ou un fragment de mot de passe vers une API externe.
| Ce que vous faites | Admis dans Réseau | Ne doit pas apparaître |
|---|---|---|
| Générer un mot de passe aléatoire | Scripts et styles de la page | Le résultat ou le jeu de caractères envoyé en POST |
| Tester une phrase ici | Une liste statique de mots faibles | Le mot de passe de la zone de saisie |
| Nettoyer un lien ou masquer un texte | Aucune requête métier portant l’original | L’URL complète, un numéro de pièce, un e-mail en clair |
| Créer un lien à usage unique | Texte chiffré, un id, expiration et nombre de lectures |
Le texte clair ; la clé # sur la ligne de requête |
| Chiffrer un fichier | Aucun envoi métier d’un corps de fichier | Les octets du fichier, la phrase |
MyPassGen est bâti sur ce tableau. Les mots de passe aléatoires font 6 à 128 caractères (16 par défaut ; sous 8, un avertissement signale un résultat faible). Le test de force utilise une liste locale, pas une confrontation sur tout le web. Nettoyage et chiffrement / déchiffrement de fichier n’envoient pas l’original comme donnée métier par défaut. Un lien à usage unique ne stocke que le texte chiffré. Chaque outil s’ouvre sans inscription. La colonne « ne doit pas apparaître » se coche dans le panneau. Inutile d’accepter d’abord une promesse de marque.
Texte chiffré qui sort n’est pas texte clair qui sort
Le partage zéro connaissance et le « totalement hors ligne » se retrouvent souvent dans la même phrase. La page Chiffrer est du second type : le résultat tombe dans le dossier Téléchargements, et le serveur n’a pas de copie métier de ce fichier. Le message autodestructif est du premier type : l’autre côté doit pouvoir retirer un blob de texte chiffré pour que le destinataire déchiffre dans son propre navigateur. Que le serveur voie le texte chiffré et ne voie pas la clé, c’est le dessin, pas un accident.
Séparez le test de fuite. À la création, une longue chaîne Base64 dans le corps POST est normale. Si le même champ se lit comme la « clé API de test » que vous venez de taper, le texte clair est parti. La requête document de la page de lecture doit être s.html?id=…. Selon la norme, l’URL de requête listée dans Réseau ne porte pas #. Ouvrez En-têtes sur cette requête et confirmez que la ligne de requête et le Referer omettent tous deux la clé.
L’étiquette d’authentification GCM rend difficile « inverser quelques octets, puis déchiffrer quand même » : si l’étiquette ne correspond pas, decrypt échoue net. Cela protège l’intégrité et l’authenticité. Cela ne dit pas que le lien ne sera jamais transféré. Quiconque a l’URL complète — y compris la clé après le dièse — peut déchiffrer jusqu’à épuisement du nombre de lectures. Réseau vérifie si le serveur a reçu la clé. Les fils de discussion, les e-mails et les captures sont un autre risque. La section suivante les traite à part.
Ne collez pas un lien à usage unique entier dans un « scanner » qui envoie l’original
La clé après # est invisible pour le serveur HTTP. Elle est entièrement visible pour le site suivant où vous la collez. Vérifiez dans vos propres outils de développement. Ne donnez pas s.html?id=…#… à une page de scan inconnue.
Ce que la norme ne couvre pas
Que HTTP n’envoie pas le fragment ne veut pas dire que la clé ne quitte jamais cet ordinateur. Un script de page peut lire window.location.hash et le fetch lui-même — c’est un défaut d’implémentation, pas un trou du protocole. La sixième étape existe pour cela : si l’analytics rapporte location.href comme URL de page, le morceau après le dièse entre dans le journal de stats. Le bon rapport est un chemin, ou une URL sans hash. « HTTP ne l’enverra pas » ne remplace pas ce soin.
L’historique du navigateur, les onglets synchronisés et certains rapports de plantage gardent l’URL complète. Laisser un lien à usage unique dans la barre d’adresse, c’est laisser la clé dans l’historique local. Partagez-le sur un canal unique ; après lecture, ne collez pas l’adresse avec # dans un modèle de ticket. Le Referer retire le fragment ; les paramètres de query peuvent encore voyager vers un tiers. Ne déplacez jamais la clé vers ?key=.
L’écran, le presse-papiers et les journaux de groupe (Slack, Teams, un fil e-mail) sont hors protocole. Un collègue qui capture le lien entier dans le chat n’a toujours pas donné la clé au serveur — et tout le fil l’a maintenant. Le chiffrement local répond à « où le calcul a-t-il eu lieu, et qui ne voit pas le texte clair par défaut ». Il ne répond pas à « la personne qui a l’URL complète va-t-elle la transférer ». La même coupure vaut pour une phrase de fichier : le .lock peut aller sur un cloud ; la phrase doit voyager par un autre canal. Un secret court va sur un lien à usage unique, pas dans le même corps d’e-mail que la phrase.
Erreurs fréquentes
« Ça échoue hors ligne, donc ça envoie forcément le texte clair. » Un lien à usage unique doit déposer le texte chiffré. L’échec hors ligne montre seulement qu’il dépend d’un transfert de texte chiffré. Lisez le contenu de ce transfert. Ne vous arrêtez pas à « il y a eu une requête ».
« HTTPS chiffre déjà le chemin, le chiffrement local est redondant. » HTTPS couvre les oreilles sur le fil. Le serveur est le point d’arrivée TLS. Il peut encore lire le corps de requête et la query. Le chiffrement local est la couche qui empêche le serveur — ou un saut d’analytics au milieu — de voir le texte clair par défaut. Il s’empile avec TLS. Les métiers sont différents.
« La page mentionne Web Crypto, donc le texte clair n’est pas envoyé. » Web Crypto ne fournit que des primitives. Chiffrer d’abord puis envoyer le texte chiffré, et poster un FormData d’abord puis chiffrer côté serveur, peuvent tous deux décorer le pied de page du même nom d’API. La charge utile du panneau prime sur le slogan.
« Je ne vois aucune requête vers l’hôte du produit, donc je suis à l’abri. » Extensions, proxies système et certaines passerelles d’entreprise ne se dessinent jamais dans la liste Réseau de la page. Le panneau peut falsifier une pub « rien n’est envoyé ». Il ne peut pas prouver qu’il n’existe aucun second canal. Pour choisir un outil en ligne au quotidien, la falsification suffit : voir du texte clair, s’arrêter.
Par où commencer
Choisissez une action jetable dont vous avez besoin aujourd’hui. Le chiffrement de fichier est le contraste le plus simple : prenez une capture sans information sensible, saisissez une phrase temporaire, ouvrez Réseau, cliquez pour chiffrer, confirmez qu’il n’y a pas de POST de corps de fichier, puis téléchargez .lock ou .enc. Quand vous envoyez cette image à quelqu’un, le texte chiffré va sur un cloud ; la phrase part dans un autre message. Un seul fichier, 5 Go au plus.
S’il s’agit d’un mot de passe d’une ligne ou d’un code de récupération, passez plutôt par un lien à usage unique : écrivez une phrase de test, générez le lien, confirmez que la requête de création ne porte que du texte chiffré ; ouvrez la page de lecture dans une fenêtre privée et vérifiez que la ligne de requête document n’a que id=. Ne traitez pas la page de lecture comme une page de contenu indexable — c’est une scène de texte chiffré à usage unique. Le nettoyage de lien suit encore le tableau de l’article précédent : retirer UTM et identifiants de clic, ici, sur cet appareil.
Après un passage, vous pouvez déjà répondre au titre : le chiffrement dans le navigateur est-il réel, ce n’est pas un slogan. C’est si ce trafic contenait du texte clair, une phrase secrète ou la clé après le dièse. AES-256-GCM, Web Crypto, et des outils qui s’ouvrent sans compte sont des contraintes que l’on peut vérifier en parallèle. Ce ne sont pas des promesses qu’il faudrait d’abord s’inscrire pour entendre.
Questions fréquentes
Pourquoi le chiffrement de fichier marche hors ligne, et pas le lien à usage unique ?
Le chiffrement de fichier se termine par un téléchargement local. Un lien à usage unique doit permettre au destinataire de retirer plus tard le texte chiffré, donc la création envoie ce texte en POST. Les deux peuvent terminer AES-256-GCM dans le navigateur. Ce qui a le droit de sortir diffère : la page Chiffrer ne doit pas avoir de corps de fichier ; la création à usage unique peut envoyer du texte chiffré et ne doit envoyer ni le texte clair ni la clé.
Le serveur ne reçoit vraiment jamais la clé après # ?
Dans les implémentations URI et HTTP ordinaires, la requête document et le Referer omettent le fragment. On le voit sur la requête document dans Réseau. Si un script lit location.hash et le rapporte, c’est le comportement de la page — cherchez-le dans la liste Fetch.
Mettre la clé dans la chaîne de requête, n’est-ce pas plus simple ?
Plus simple, et elle atterrit dans les journaux serveur. ?id= peut localiser le texte chiffré. ?key= donne la capacité de déchiffrement à l’hôte et à chaque journal sur le chemin. Quand le destinataire doit déchiffrer et l’hôte ne doit pas, la clé va après #.
Faut-il un compte pour ce contrôle ? L’analytics emporte-t-il l’original ?
Aucun compte. Si l’analytics enregistre un type de page ou un chemin sans hash, il n’emporte pas le contenu de la zone de saisie. S’il rapporte le href complet, la clé après # peut entrer dans le journal de stats. Lire la query de la requête analytics dans Réseau est plus direct que lire « nous respectons la vie privée ».