L’essentiel
Base64 permet d’écrire n’importe quelle suite d’octets avec 64 caractères sûrs (A–Z, a–z, 0–9, +, /). Il existe pour que des données binaires (une image, un PDF, une clé) puissent transiter par des systèmes qui ne gèrent que du texte : corps d’e-mails, chaînes JSON, URL, attributs HTML. C’est de l’encodage, pas du chiffrement : il n’y a aucune clé, et le décodage tient en un seul appel de fonction, disponible dans tous les langages et dans la console développeur de tous les navigateurs. Un mot de passe stocké « en Base64 » est un mot de passe stocké en clair, avec une étape de plus.
Pourquoi il existe
L’e-mail a été conçu dans les années 1970 pour l’ASCII 7 bits. Quand les pièces jointes sont arrivées (MIME, 1992), il a fallu déguiser en texte inoffensif les octets d’un JPEG, qui utilisent les 256 valeurs possibles, y compris celles qui signifient « fin de ligne » ou « fin de message » pour un serveur de messagerie. Base64 a été la réponse : prendre trois octets (24 bits), les découper en quatre groupes de 6 bits, et associer chaque groupe à l’un des 64 caractères. Chaque bloc de 3 octets devient 4 caractères, d’où le fameux surcoût de 33 % : une pièce jointe de 3 Mo donne un e-mail de 4 Mo, et c’est pourquoi une limite de « 25 Mo » laisse passer un fichier de 18 Mo.
On retrouve la même astuce partout où le texte est le seul canal : intégrer une petite image directement dans une page web (data:image/png;base64,…), placer un jeton binaire dans un en-tête HTTP (Authorization: Basic …), transporter certificats et clés dans des fichiers PEM, ou glisser un tableau d’octets dans un champ JSON.
Les variantes qui piègent
- Standard ou compatible URL. Le Base64 standard utilise
+et/, deux caractères qui ont un sens dans une URL. L’alphabet compatible URL (RFC 4648 §5) les remplace par-et_. Un jeton produit avec l’un et décodé avec l’autre échoue sur ces deux caractères. Les JWT utilisent la forme compatible URL. - Le remplissage. La longueur de la sortie est toujours un multiple de quatre, complétée par des
=. Certains producteurs suppriment ce remplissage (les JWT, encore eux) ; certains décodeurs l’exigent. Si le décodage échoue sur une chaîne par ailleurs valide, ajoutez des=jusqu’à ce que la longueur soit divisible par quatre. - Les retours à la ligne. MIME coupe les lignes à 76 caractères, PEM à 64. Les décodeurs ignorent en général les espaces et sauts de ligne, mais pas tous.
- L’encodage du texte en dessous. Base64 encode des octets. Pour passer une chaîne en Base64, il faut d’abord la convertir en octets, et le choix entre UTF-8, UTF-16 ou Latin-1 change le résultat. Le bug JavaScript classique,
btoa("é")qui lève une erreur, vient exactement de là :btoan’accepte que le Latin-1. Encodez d’abord en octets UTF-8.
L’outil Base64 gère les deux alphabets, le remplissage, les retours à la ligne et l’UTF-8, et décode soit en texte, soit en fichier téléchargeable : une URL data: ou une pièce jointe d’e-mail peut ainsi retrouver sa forme d’origine dans le navigateur.
Encoder, hacher, chiffrer
Ces trois mots sont employés indifféremment dans le langage courant, alors qu’ils désignent des choses complètement différentes.
| Réversible ? | Clé nécessaire ? | Usage | |
|---|---|---|---|
| Encodage (Base64, hexadécimal, encodage URL) | Oui, par n’importe qui | Non | Adapter les données à un canal |
| Hachage (SHA-256, MD5) | Non | Non | Prendre l’empreinte des données ; vérifier qu’elles n’ont pas été modifiées |
| Chiffrement (AES, RSA) | Oui, avec la clé | Oui | Garder les données secrètes pour quiconque n’a pas la clé |
Le hash d’un fichier permet de vérifier qu’un téléchargement correspond à ce que l’éditeur a publié : le Générateur de hash calcule MD5, SHA-1 et SHA-256/384/512 dans le navigateur et compare le résultat à une somme de contrôle collée. Il ne cache rien : le fichier reste le fichier. Le chiffrement est le seul des trois à garantir le secret, et il ne vaut que ce que vaut la clé. C’est là qu’intervient un mot de passe réellement aléatoire.
Si vous alliez encoder un secret en Base64
Ne le faites pas. Concrètement :
- Les fichiers de configuration avec mots de passe en Base64 (une pratique courante dans les anciennes applications Java et .NET) contiennent des mots de passe en clair pour quiconque ouvre le fichier.
- Les clés d’API « masquées » dans le JavaScript côté client sont visibles dans l’onglet Réseau, Base64 ou pas.
- L’authentification Basic sur du HTTP simple envoie l’identifiant et le mot de passe encodés en Base64, c’est-à-dire en clair. Elle n’est acceptable qu’à l’intérieur de HTTPS, où c’est la couche de transport qui chiffre.
Si des données doivent être stockées ou envoyées en restant secrètes, chiffrez-les avec un vrai algorithme (AES-256-GCM via la bibliothèque cryptographique de la plateforme), puis, si elles doivent passer par un canal texte, encodez le texte chiffré en Base64. Encoder après avoir chiffré ne pose aucun problème. L’erreur, c’est d’encoder à la place de chiffrer.