Base64 expliqué: comment ça marche, quand l'utiliser et quand pas
Une explication claire de l'encodage Base64: l'algorithme, le remplissage, l'URL sécurisée Base64, les URL de données, les frais généraux de taille, les pièges Unicode et les idées fausses de sécurité.
· 6 min de lecture
Base64 apparaît dans les pièces jointes de courrier électronique, les jetons Web JSON, les URL de données, les secrets Kubernetes, l'authentification HTTP Basic et d'innombrables API qui doivent déplacer des données binaires via des canaux de texte uniquement. Il est simple une fois que vous voyez comment il fonctionne, mais il est souvent mal utilisé surtout comme s'il s'agissait d'un cryptage. Cet article explique l'algorithme étape par étape, les variantes courantes, et des conseils pratiques sur quand Base64 est le bon outil.
Le problème résolu par Base64
Beaucoup de systèmes ont été conçus pour transporter du texte, pas des octets arbitraires. Le courrier électronique (SMTP) n'a historiquement pris en charge que l'ASCII à 7 bits. Les chaînes JSON ne peuvent pas contenir du binaire brut. Les URL et les en-têtes HTTP ont des jeux de caractères restreints. Si vous mettez les octets bruts d'une image dans l'un d'entre eux, certains octets seront interprétés comme des caractères de contrôle, des extrémités de ligne ou des délimitateurs, et les données seront corrompues.
Base64 cartographie des octets arbitraires sur 64 caractères sûrs et imprimables: A–Z, a–z, 0–9, + et /. Tout système qui peut transporter du texte brut peut alors transporter les données intactes.
Comment fonctionne le codage
Base64 traite l'entrée en groupes de 3 octets (24 bits) et sort 4 caractères de 6 bits chacun. Puisque 2 ^ 6 = 64, chaque valeur de 6 bits sélectionne un caractère de l'alphabet.
Prenez le mot Man:
- Les octets ASCII:
M= 77,a= 97,n= 110. - En binaire:
01001101 01100001 01101110. - Divisé en quatre groupes de 6 bits:
010011 010110 000101 101110. - En chiffres: 19, 22, 5, 46.
- Regardez dans l'alphabet:
T,W,F,u.
Donc Man devient TWFu. Le décryptage inverse le processus.
Le remplissage avec =
Lorsque la longueur d'entrée n'est pas un multiple de 3, le dernier groupe est incomplet. Base64 le remplit:
- 1 octet restant produit 2 caractères plus
==. - 2 octets restants produisent 3 caractères plus
=.
Ma code pour TWE= et M pour TQ==. Le remplissage rend la longueur de sortie un multiple de quatre, ce que certains décodeurs exigent. D'autres, en particulier les implémentations sécurisées par URL, l'omettent parce que la longueur implique déjà combien d'octets manquent.
Taille des frais généraux
Tous les 3 octets deviennent 4 caractères, donc la sortie Base64 est environ 33% plus grande que l'entrée, plus le rembourrage et parfois les ruptures de ligne (le courrier électronique MIME enveloppe les lignes à 76 caractères). Une image de 1 Mo devient environ 1,37 Mo de texte. Ce surcoût est important lorsque vous intégrez de gros fichiers en JSON ou HTML.
Base64 sécurisé par URL
L'alphabet standard comprend + et /, qui ont des significations spéciales dans les URL, et = qui est utilisé dans les chaînes de requêtes. Base64URL, défini dans la RFC 4648, remplace + par - et / par _, et supprime généralement le rembourrage. Les JWT, de nombreux jetons API et touches web push utilisent cette variante voir comment fonctionne JWT pour un exemple.
Un décodeur standard échoue sur - et _, et vice versa, ce qui est une source commune d'erreurs de caractère invalide. Un décodeur tolérant [Base64] ((/tools/base64) accepte les deux alphabets et rétablit automatiquement le rembourrage manquant.
Texte, octets et Unicode
Base64 encode les octets, pas les caractères. Pour encoder du texte, vous devez d'abord le convertir en octets avec un codage de caractères, presque toujours UTF-8. C'est là que les navigateurs font trébucher les gens: btoa() intégré à JavaScript accepte uniquement les caractères de la gamme Latin-1, donc btoa("héllo") fonctionne par accident et btoa("你好") lance une erreur.
L'approche correcte dans JavaScript moderne:
const bytes = new TextEncoder().encode("你好 👋");
const b64 = btoa(String.fromCharCode(...bytes));
const back = new TextDecoder().decode(Uint8Array.from(atob(b64), c => c.charCodeAt(0)));
D'autres langages le rendent explicite: le base64.b64encode de Python prend des octets, donc vous écrivez base64.b64encode("你好".encode("utf-8")).
URL des données
Une URL de données intègre un fichier directement dans HTML ou CSS:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." alt="">
Cela sauve une requête HTTP, qui était précieuse à l'époque HTTP/1.1. Aujourd'hui, avec le multiplexage HTTP/2, les compromis favorisent généralement des fichiers séparés:
- Les URL de données ne peuvent pas être mises en cache indépendamment; elles sont à nouveau téléchargées avec chaque page ou feuille de style qui les contient.
- Ils gonflent HTML et CSS, ce qui bloque le rendu jusqu'à ce qu'il soit téléchargé et analysé.
- La charge de 33% s'applique, bien que gzip récupère une partie de celui-ci.
Utilisez des URL de données pour de minuscules actifs petites icônes de moins de 1 2 Ko, images de placeholder ou exportations HTML en un seul fichier. Pour tout ce qui est plus grand, servez un fichier normal et [comprimez-le] ((/blog/comprimez-image-à-100kb) à la place.
Base64 n'est pas un chiffrement.
C'est le point le plus important. Base64 n'a pas de clé. N'importe qui peut le décoder instantanément, et beaucoup d'outils le font automatiquement. Pourtant, il est fréquent de constater:
- Les clés API sont "cachées" dans Base64 dans le code front-end.
- Les mots de passe sont stockés en base64 dans des bases de données ou des fichiers de configuration.
- Les secrets Kubernetes sont présumés protégés parce que leurs valeurs sont Base64.
Kubernetes encode des valeurs secrètes en Base64 purement pour que les données binaires s'intègrent dans YAML; la protection provient du contrôle d'accès et du chiffrement au repos, qui doivent être configurés séparément. Si les données doivent être confidentielles, chiffrez-les avec un véritable algorithme tel que AES-GCM, et si vous devez vérifier les mots de passe, utilisez une fonction de hachage de mot de passe pas Base64 et pas un simple hachage comme MD5 (pourquoi pas).
Cas d'utilisation courants bien faits
- ** L'authentification de base HTTP** envoie
Authorization: Basic base64(user:password). Le codage évite uniquement les problèmes avec les caractères spéciaux; les informations d'identification sont protégées uniquement par HTTPS. - ** Les pièces jointes aux courriels** utilisent MIME Base64 avec des interruptions de ligne toutes les 76 lettres.
- ** L'intégration de données binaires dans JSON**, comme une petite image de signature ou une clé cryptographique, est une utilisation légitime. Pour les fichiers volumineux, télécharger séparément et les référencer par URL.
- Enregistrement binaire en configuration texte uniquement, comme les certificats TLS dans des variables d'environnement.
Résolution de problèmes d'erreurs de décodage
- Charactre invalide: vous décodez probablement Base64URL avec un décodeur standard, ou la chaîne contient des espaces ou des pauses de ligne.
- Emboutissage incorrect: ajouter
=jusqu'à ce que la longueur soit un multiple de quatre. - Texte déformé après le décryptage: l'original a été codé à partir d'un ensemble de caractères différent, ou les données sont binaires plutôt que texte.
- La sortie ressemble à Base64 à nouveau: les données ont été codées deux fois; décoder une fois de plus.
Codes connexes
- Base32 utilise 32 caractères (AZ et 27), est insensible à la majuscule et est utilisé dans les secrets TOTP pour les applications d'authentification. Les frais généraux sont de 60%.
- Hexadecimal (Base16) utilise deux caractères par octet 100% de frais généraux mais est facile à lire et commun pour les hachages.
- Base58 supprime les caractères similaires et est utilisé dans les adresses Bitcoin.
- %-encoding échappe uniquement aux caractères dangereux dans les URL.
Résumé
Base64 convertit des octets en un alphabet de texte de 64 caractères, 3 octets à la fois, au coût d'environ 33% de taille supplémentaire. Utilisez-le pour transporter des données binaires via des canaux de texte; utilisez la variante URL-safe dans les URL et les jetons; convertissez toujours le texte en octets UTF-8 en premier. Ne l'utilisez jamais pour protéger des secrets c'est un cryptage, pas un verrou.
Cette page a été traduite automatiquement depuis l'anglais. Si vous repérez une erreur, dites-le-nous.