La différence entre base64url et base64 se résume à trois petits changements : le base64 standard utilise + et / dans son alphabet ainsi que le remplissage =, tandis que le base64url remplace + par -, / par _ et supprime généralement le remplissage =. C'est toute la différence au niveau de la spécification. Tout le reste, le calcul de codage, le regroupement en 6 bits, le surcoût de taille de 33 %, est identique entre les deux.
Pourquoi est-ce important ? Parce que +, / et = ont tous des significations réservées dans les URL, les chaînes de requête et les noms de fichiers. Si vous insérez une chaîne base64 standard dans une URL, + peut être interprété comme un espace, / commence un nouveau segment de chemin et = ressemble à une affectation de paramètre. Base64url existe pour que les données encodées survivent à ces contextes sans modification. Ce guide couvre exactement quand chaque variante est requise, le piège du re-remplissage que la plupart des articles omettent, et pourquoi les JSON Web Tokens utilisent base64url pour leur en-tête et leur charge utile.
Base64url vs Base64 : la différence fondamentale#
Les deux variantes sont définies dans la RFC 4648. Le base64 standard se trouve dans la section 4 ; l'alphabet sûr pour les URL et les noms de fichiers dans la section 5. Ils encodent les octets de la même manière : prenez trois octets (24 bits), divisez-les en quatre groupes de 6 bits, et mappez chaque groupe à un caractère d'un alphabet de 64 caractères. La seule chose qui change est quels caractères occupent les deux dernières positions de cet alphabet et si vous ajoutez du remplissage à la fin.
Voici le comparatif qui compte vraiment :
| Aspect | Base64 standard | Base64url |
|---|---|---|
| Caractère d'index 62 | + (plus) | - (trait d'union) |
| Caractère d'index 63 | / (barre oblique) | _ (trait de soulignement) |
| Remplissage | = pour un multiple de 4 | Généralement omis |
| Sûr dans les URL / chaînes de requête | Non | Oui |
| Sûr dans les noms de fichiers | Non (le / casse les chemins) | Oui |
| Section RFC 4648 | Section 4 | Section 5 |
| Longueur de sortie | Identique | Identique |
Remarquez que les 62 premiers caractères (A-Z, a-z, 0-9) sont les mêmes dans les deux alphabets. Seules les positions 62 et 63 diffèrent. C'est pourquoi la conversion entre les deux est une simple substitution de caractères et ne nécessite jamais de ré-encoder les octets d'origine.
Astuce rapide : si vous voyez une chaîne ressemblant à du base64 avec
-ou_, vous avez presque certainement affaire à du base64url. Le base64 standard n'utilise jamais ces deux caractères.
Pourquoi + et / posent problème dans les URL#
Une URL a une grammaire, et plusieurs caractères ont une signification structurelle. La barre oblique / sépare les segments de chemin. Le plus + est historiquement interprété comme un espace encodé dans les données application/x-www-form-urlencoded (le format utilisé par les chaînes de requête et les formulaires). Le signe égal = sépare un nom de paramètre de requête de sa valeur.
Donc, si vous mettez un jeton base64 standard comme a+b/c= directement dans une URL, un serveur pourrait décoder le + en espace, traiter /c comme un nouveau chemin, et lire = comme le début d'une valeur. Vos données sont alors corrompues avant même que votre code ne les touche. Base64url contourne tout le problème en n'émettant jamais aucun de ces trois caractères.
Quand utiliser chaque variante#
La règle de décision est simple. Utilisez base64url partout où la sortie transite par une URL, un paramètre de requête, un en-tête HTTP, un nom de fichier ou un cookie. Utilisez le base64 standard pour tout le reste : pièces jointes d'email (MIME), URI de données, fichiers de configuration, valeurs de chaîne JSON qui ne sont pas liées à une URL et blobs binaires stockés dans une base de données.
Utilisez base64url lorsque la valeur encodée apparaîtra dans :
- Un chemin d'URL ou une chaîne de requête (par exemple
?token=...) - Un JWT (en-tête, payload et signature sont tous en base64url)
- Un paramètre OAuth ou OpenID Connect comme
stateoucode_challenge - Un nom de fichier ou une clé d'objet S3 (le
/dans le base64 standard créerait des dossiers involontaires) - Les clés WebPush, les identifiants FIDO/WebAuthn et de nombreux autres contextes cryptographiques web
Utilisez le base64 standard lorsque la valeur se trouve dans :
- Une pièce jointe d'email encodée en MIME
- Une URI
data:intégrée dans du HTML ou du CSS (ceux-ci tolèrent bien+et/) - Une valeur de configuration JSON ou YAML qui n'est jamais placée dans une URL
- Une colonne de base de données ou une ligne de journal
Si vous n'êtes pas sûr de la variante à utiliser, collez-la dans le encodeur et décodeur base64 gratuit et décodez-la des deux manières. Si une seule variante produit une sortie propre et lisible, cela vous indique quel alphabet l'a produite.
Le piège du padding que la plupart des guides omettent#
C'est la partie qui fait trébucher les gens et la raison pour laquelle un extrait copié génère parfois une erreur. Le base64 standard ajoute du remplissage avec = pour que la longueur totale soit toujours un multiple de 4. Le base64url supprime normalement ce remplissage car = est lui-même dangereux dans les URL.
Le calcul : le base64 encode 3 octets en 4 caractères. Lorsque votre entrée n'est pas un multiple de 3 octets, l'encodeur comble le vide avec =. Un octet restant produit deux caractères de remplissage (==), deux octets restants en produisent un (=).
Voici le piège. De nombreux décodeurs stricts exigent une longueur qui est un multiple de 4. Lorsque le base64url supprime le remplissage, la longueur de la chaîne n'est plus un multiple de 4, donc un décodeur naïf échoue. La solution est de rajouter le remplissage avant de décoder.
Comment rajouter le remplissage du base64url avant de décoder#
Pour décoder en toute sécurité une chaîne base64url avec un décodeur base64 générique, faites deux choses : reconvertissez l'alphabet (- en +, _ en /), puis ajoutez = jusqu'à ce que la longueur soit un multiple de 4.
En JavaScript :
function base64urlDecode(input) {
// 1. Restaurer l'alphabet standard
let b64 = input.replace(/-/g, '+').replace(/_/g, '/');
// 2. Rajouter le remplissage pour obtenir un multiple de 4
const pad = b64.length % 4;
if (pad === 2) b64 += '==';
else if (pad === 3) b64 += '=';
else if (pad === 1) throw new Error('Longueur base64url invalide');
return atob(b64);
}
Un reste de longueur de 1 est impossible dans un base64 valide, donc traitez-le comme une entrée malformée plutôt que de deviner. Si vous sautez l'étape de rajout du remplissage, atob et la plupart des décodeurs côté serveur rejetteront la chaîne ou renverront des données erronées. Notre codec base64 gère automatiquement le rajout du remplissage, vous pouvez donc insérer un jeton base64url non rempli et il le décode sans que vous ayez à faire le calcul.
Pourquoi les JWT utilisent le Base64url (et non le Base64)#
Un JSON Web Token est constitué de trois segments en base64url reliés par des points : header.payload.signature. La raison pour laquelle il utilise le base64url et non le base64 standard est exactement le problème évoqué ci-dessus. Les tokens sont transmis dans des URL, dans des en-têtes Authorization: Bearer et dans des paramètres de requête lors des flux OAuth. Un token en base64 standard contenant un / ou un + serait cassé dès qu'il atteindrait une URL.
Ainsi, la spécification JWT (RFC 7519, basée sur RFC 7515) impose le base64url sans remplissage. C'est pourquoi un JWT ne contient jamais =, + ou /, seulement des lettres, des chiffres, des traits d'union, des underscores et les deux points séparateurs.
Attention : le base64url est un encodage, pas un chiffrement. N'importe qui peut décoder le payload d'un JWT et lire ses revendications. Ne mettez jamais de secrets dans le corps d'un JWT. La signature prouve que le token n'a pas été altéré, mais elle ne cache pas son contenu.
Si vous souhaitez inspecter un token, vous pouvez séparer les trois segments et décoder en base64url l'en-tête et le payload avec l'outil de décodage JWT. Il effectue la conversion d'alphabet et le re-padding pour vous, afin que vous voyiez instantanément les revendications JSON brutes. Pour comprendre ce que prouve le segment de signature par rapport à ce que montre le simple décodage, l'analyse dans décoder vs vérifier un JWT mérite d'être lue avant de faire confiance à un token en production.
Conversion entre les deux variantes#
Comme seuls deux caractères et le rembourrage diffèrent, la conversion est une simple manipulation de chaîne. Vous ne relancez jamais l'algorithme base64.
Base64 standard vers base64url :
- Remplacez chaque
+par- - Remplacez chaque
/par_ - Supprimez les caractères
=de fin
Base64url vers base64 standard :
- Remplacez chaque
-par+ - Remplacez chaque
_par/ - Ajoutez le rembourrage
=jusqu'à ce que la longueur soit un multiple de 4
Cette symétrie est l'essentiel à retenir : les deux formats représentent les mêmes données avec des habillages différents. Si un décodage échoue, la cause est presque toujours une incompatibilité (vous avez fourni du base64url à un décodeur standard sans conversion) ou un rembourrage manquant, pas des données corrompues.
Un exemple concret#
Prenez les octets de la chaîne Hello?>. Le base64 standard l'encode en SGVsbG8/Pg==. Notez le / à l'index 8 et le rembourrage ==. En base64url, les mêmes octets deviennent SGVsbG8_Pg : le / est maintenant _ et le rembourrage a disparu. Décodez l'un ou l'autre et vous obtenez Hello?>. Même contenu, deux représentations sûres dans des contextes différents.
Erreurs courantes et comment les éviter#
Quelques erreurs reviennent souvent lorsque les développeurs mélangent les deux variantes :
- Décoder du base64url avec un décodeur standard et obtenir une erreur. Convertissez d'abord
-/_en+//et rajoutez le padding. C'est l'erreur la plus fréquente. - Supposer que
=est toujours présent. Un code qui découpe ou valide la longueur du padding échoue dès qu'il rencontre du base64url non paddé. Rendez le padding optionnel dans votre analyse. - Encoder en URL une chaîne base64 standard au lieu d'utiliser base64url. Cela fonctionne mais alourdit la sortie :
+devient%2B,/devient%2F. Base64url est plus court et plus propre pour les contextes URL. - Considérer base64 ou base64url comme une couche de sécurité. Les deux sont réversibles par n'importe qui. Utilisez-les pour transporter du binaire sous forme de texte, jamais pour protéger des données.
- Oublier que les deux formats ont le même surcoût de taille de 33%. Coder 3 octets en 4 caractères signifie que votre sortie est environ un tiers plus grande que l'entrée brute, quelle que soit la variante.
Si vous manipulez du binaire encodé comme des images avec du texte, le guide sur comment encoder et décoder des images base64 et des data URLs couvre le côté data-URI où le base64 standard est le bon choix.
Foire aux questions#
Base64url est-il identique au base64 ?
Non, mais ils sont proches. Base64url utilise exactement le même algorithme de codage et produit une sortie de même longueur. Les seules différences sont que + devient -, / devient _, et le remplissage = est généralement supprimé pour que la chaîne soit sûre à utiliser dans les URL et les noms de fichiers.
Pourquoi base64url supprime-t-il le remplissage ?
Le caractère de remplissage = a une signification réservée dans les URL (il sépare un nom de paramètre de requête de sa valeur), donc le laisser pourrait corrompre les données ou confondre un serveur. Base64url le supprime pour des raisons de sécurité. L'inconvénient est que les décodeurs stricts peuvent exiger que vous rajoutiez le remplissage avant de décoder.
Puis-je décoder base64url avec un décodeur base64 normal ?
Oui, mais seulement après deux étapes. D'abord, reconvertissez l'alphabet en remplaçant - par + et _ par /. Ensuite, rajoutez le remplissage = jusqu'à ce que la longueur de la chaîne soit un multiple de 4. Si vous sautez l'une ou l'autre étape, la plupart des décodeurs standard généreront une erreur ou renverront des données inutilisables.
Pourquoi les JWT utilisent-ils base64url plutôt que le base64 standard ?
Parce que les jetons transitent par des URL, des en-têtes HTTP et des paramètres OAuth où +, / et = poseraient problème. La spécification JWT impose base64url sans remplissage, c'est pourquoi vous ne voyez jamais ces trois caractères dans un jeton Web JSON valide, seulement des lettres, des chiffres, des traits d'union, des underscores et des points séparateurs.
Base64url est-il un chiffrement ou simplement un encodage ? C'est uniquement un encodage. N'importe qui peut l'inverser sans clé, exactement comme le base64 standard. Il existe pour représenter des données binaires sous forme de texte compatible URL, pas pour garder quoi que ce soit secret. Ne stockez jamais de mots de passe, de clés API ou d'autres données sensibles en base64url en pensant qu'elles sont protégées.
Base64url produit-il une chaîne plus petite que base64 ?
Légèrement, uniquement parce qu'il omet généralement le remplissage = (économisant zéro à deux caractères). Le corps encodé a la même longueur dans les deux cas. Les deux variantes ajoutent le même surcoût d'environ 33 % par rapport au binaire brut, car tous les 3 octets deviennent 4 caractères.
Base64url vs base64 n'est pas un mystère profond une fois que vous le voyez comme un alphabet avec deux caractères échangés et un remplissage optionnel. Utilisez base64url chaque fois que vos données touchent une URL, un en-tête, un nom de fichier ou un JWT, et le base64 standard pour MIME, les URI de données et le stockage. Lorsqu'un décodage échoue, suspectez d'abord une incompatibilité de variante ou un remplissage manquant, puis insérez la chaîne dans le codeur et décodeur base64 pour confirmer quel alphabet vous avez.



