Accueil

/

Blog

/

Chiffrement navigateur

Chiffrement dans le navigateur : comment ça fonctionne réellement

Technique
Cryptographie
Web Crypto API
9 min de lecture

Par Simon Themiot - consultant cybersécurité freelance. Publié le 19 mai 2026.

En résumé

  • La Web Crypto API est une interface native des navigateurs modernes qui permet de chiffrer des données directement côté client, sans aucune extension ni plugin.
  • Quand l'option E2E est activée dans PrivCloud, le fichier est chiffré avec AES-256-GCM par enregistrements authentifiés de 1 Mo. Les chunks de transport sont dimensionnés séparément pour le réseau et le stockage objet.
  • Le serveur ne reçoit alors ni le contenu en clair ni sa clé. Il conserve toutefois les métadonnées nécessaires au service et délivre le code client, qui reste dans le modèle de confiance.

1. La Web Crypto API en 2 minutes

La Web Crypto API (accessible via window.crypto.subtle) est un standard W3C implémenté nativement dans Chrome, Firefox, Safari et Edge depuis 2017. Elle expose des primitives cryptographiques de bas niveau directement dans le navigateur :

  • Génération de clés : generateKey() crée des clés AES, RSA, EC directement dans la mémoire protégée du navigateur.
  • Chiffrement/déchiffrement : encrypt() / decrypt() avec AES-GCM, AES-CBC, RSA-OAEP.
  • Dérivation de clé : deriveKey() avec PBKDF2, HKDF pour transformer un mot de passe en clé cryptographique.
  • Hachage : digest() avec SHA-256, SHA-384, SHA-512.
  • Aléa cryptographique : getRandomValues() pour générer des IV, nonces et sels imprévisibles.

Les primitives sont exécutées par l'implémentation native du navigateur. Une clé créée avec extractable: false ne peut pas être exportée sous forme brute, mais le JavaScript autorisé peut encore demander au navigateur de l'utiliser. Pour un partage par lien, PrivCloud crée volontairement une clé exportable afin de l'encoder dans le fragment d'URL : la sécurité dépend donc aussi de l'intégrité du JavaScript servi et du poste client.

2. Le workflow complet : du fichier clair au fichier chiffré

Voici les étapes exactes qui se produisent lorsque vous déposez un fichier sur un service E2E comme PrivCloud :

  1. Génération de la clé maître : Le navigateur appelle crypto.subtle.generateKey() pour créer une clé AES-256 aléatoire. Elle est générée localement puis exportée uniquement afin de construire le fragment du lien de partage.
  2. Lecture du fichier : Un Web Worker lit le fichier avec Blob.slice(). Les chunks de transport font entre 6 et 35 Mo sans compte et jusqu'à 50 Mo pour les profils authentifiés, selon le débit mesuré. Le navigateur borne uniquement son usage mémoire/CPU ; le serveur attribue ensuite une fenêtre réseau équitable, recalculée selon les ressources disponibles.
  3. Chiffrement par enregistrements : À l'intérieur de chaque chunk de transport, le worker chiffre des enregistrements de 1 Mo avec crypto.subtle.encrypt(). Un IV unique de 12 octets est généré pour chaque enregistrement via getRandomValues().
  4. Authentification intégrée : AES-GCM produit un tag d'authentification de 128 bits pour chaque enregistrement. Toute modification (même d'un seul bit) sera détectée au déchiffrement. Aucun HMAC séparé n'est nécessaire.
  5. Envoi des chunks chiffrés : Les chunks contenant les enregistrements chiffrés (données + IV + tag) sont envoyés via HTTPS. Une requête légère préinitialise la session multipart afin que les parts puissent démarrer ensemble. Le backend les transmet au stockage sans pouvoir les déchiffrer.
  6. Construction du lien : La clé maître est encodée en Base64url et placée dans le fragment de l'URL (#). Ce fragment n'est jamais transmis au serveur par le navigateur (spécification RFC 3986).

3. Où va la clé ? Le fragment d'URL

C'est le point clé (sans mauvais jeu de mots) de l'architecture E2E dans le navigateur. L'URL de partage a cette structure :

https://share.privcloud.fr/s/abc123#key=clé-de-déchiffrement-en-base64url

La partie après le # est le "fragment identifier". Selon la RFC 3986 et le comportement de tous les navigateurs, cette partie :

  • N'est jamais envoyée au serveur dans la requête HTTP
  • N'apparaît pas dans les logs serveur
  • N'est pas transmise dans le header Referer aux sites tiers
  • Est traitée exclusivement par le JavaScript côté client

Concrètement : quand le destinataire ouvre le lien, son navigateur fait une requête GET à /s/abc123 (sans le fragment). Le serveur renvoie la page HTML + le fichier chiffré. Le JavaScript de la page lit le fragment, décode la clé, et déchiffre le fichier localement. À aucun moment le serveur n'a accès à la clé.

Le mot de passe optionnel de PrivCloud est une barrière d'accès complémentaire : il est vérifié côté serveur à partir d'un hash Argon2 avant la délivrance du jeton de téléchargement. Il ne chiffre pas la clé E2E, qui reste dans le fragment. Il protège donc contre la fuite isolée du lien, mais ne remplace ni le chiffrement E2E ni un canal de transmission séparé.

4. Limites et garanties

Le chiffrement côté navigateur n'est pas magique. Voici ce qu'il garantit et ce qu'il ne garantit pas :

Ce qui est garanti

  • Le stockage serveur seul ne permet pas de lire le contenu sans la clé E2E
  • Un attaquant qui intercepte le trafic HTTPS ne voit que des données déjà chiffrées
  • L'intégrité est vérifiée : toute altération est détectée (tag GCM)
  • Le code source est auditable (open source sur GitHub)

Ce qui n'est pas garanti

  • Si votre machine est compromise (keylogger, malware), l'attaquant peut capturer la clé en mémoire
  • Si le fournisseur du service modifie le JavaScript pour exfiltrer la clé (d'où l'importance de l'open source et des audits)
  • Si vous partagez le lien complet (avec fragment) sur un canal non sécurisé, le destinataire non prévu peut déchiffrer
  • Les métadonnées (nom du fichier, taille, date d'upload) peuvent rester visibles côté serveur selon l'implémentation

5. FAQ

Le chiffrement navigateur est-il aussi sûr qu'une application native ?

En termes de primitives cryptographiques, oui : la Web Crypto API utilise les mêmes algorithmes (AES-256-GCM) que les applications natives. La différence est le modèle de confiance : avec une app native, vous faites confiance au binaire installé. Avec le web, vous faites confiance au JavaScript servi à chaque visite. C'est pourquoi l'open source, les en-têtes de sécurité et la maîtrise de la chaîne de build sont essentiels.

Quelle taille de fichier peut-on chiffrer dans le navigateur ?

Le traitement par chunks et le Web Worker évitent de charger le fichier entier en RAM. PrivCloud prévoit des transferts de plusieurs centaines de Go, jusqu'aux limites configurées de l'offre Team. La faisabilité réelle dépend toutefois du navigateur, de l'espace disque disponible pour l'écriture en flux, de la stabilité réseau et des limites du plan ; elle ne doit donc pas être présentée comme illimitée.

Pourquoi ne pas utiliser RSA pour tout chiffrer ?

RSA est adapté à de petites quantités de données, pas au chiffrement direct d'un gros fichier. Un schéma hybride protège une clé symétrique avec un mécanisme asymétrique, puis chiffre le contenu avec AES. Pour les partages Team, {appName} enveloppe les clés de fichiers pour les membres avec X25519 et peut ajouter ML-KEM-768 ; les partages par lien transmettent leur clé via le fragment d'URL.

Le mode navigation privée change-t-il quelque chose ?

Pour le chiffrement lui-même, non. La Web Crypto API fonctionne de la même manière en navigation privée. L'avantage de la navigation privée est que le fragment d'URL (contenant la clé) ne sera pas sauvegardé dans l'historique local à la fermeture de l'onglet.

À lire aussi

Testez le chiffrement navigateur en action

PrivCloud implémente ce workflow avec AES-256-GCM côté client, clé dans le fragment pour les partages par lien, enregistrements E2E de 1 Mo et transport adaptatif. Le mot de passe optionnel ajoute un contrôle d'accès côté serveur, distinct du chiffrement. Code source ouvert et hébergement en France.

Essayer PrivCloud

Cet article est fourni à titre éducatif. Les détails d'implémentation peuvent varier selon les versions. Consultez le code source sur GitHub pour les spécificités exactes. Dernière mise à jour : 14 juillet 2026.