Français

Outils de développement · Encodeur et décodeur Base64

RFC 4648 expliqué : la norme qui définit Base64, base32 et base16

· Contexte

base64 codage

RFC 4648 familles d'alphabets : base64, base64url, base32, base32hex, base16
Illustration vectorielle originale de ToolAcre

RFC 4648 est le document court et lisible derrière chaque implémentation Base64. Cet article passe en revue ce qu'il spécifie, ce qu'il laisse délibérément ouvert et pourquoi les implémentations diffèrent encore. En-tête

Deux bibliothèques, deux réponses pour une même chaîne — un véritable casse-tête d'interopérabilité que seul le standard règle

Deux bibliothèques JavaScript peuvent renvoyer des Base64 différents pour la même chaîne, chacune revendiquant l'exactitude. La RFC 4648 est le document lisible de douze pages qui devrait régler de tels désaccords, mais les implémentations diffèrent encore car la RFC laisse délibérément certaines décisions aux applications. Cet article passe en revue ce que spécifie la RFC 4648, ce qu'elle délègue intentionnellement aux appelants et pourquoi la lecture de la norme une fois résout la plupart des véritables énigmes d'interopérabilité. L'outil d'encodage et de décodage Base64 comprend des vecteurs de test RFC 4648 afin que vous puissiez vérifier une implémentation par rapport aux exemples faisant autorité.

RFC 4648 a remplacé et consolidé plusieurs documents antérieurs : Base64 de MIME (RFC 2045), Base64 de Privacy-Enhanced Mail (RFC 1421), base32 de S/MIME (RFC 2630) et base16 de diverses sources. La consolidation était nécessaire car MIME et PEM avaient chacun leur propre alphabet et leurs propres règles, et le retour à la ligne MIME était en conflit avec les blocs de colonnes 64 de PEM. La RFC 4648 définit cinq familles de codage en un seul endroit : base64, base64url, base32, base32hex et base16, chacune avec son propre alphabet, ses règles de remplissage et ses exemples de vecteurs de test. L'alphabet base64 est A-Z, a-z, 0-9, plus et slash, dans cet ordre.

Ce que l'implémentation et les vecteurs de test établissent : alphabets standard et sécurisés pour les URL, remplissage et gestion des espaces

Chaque caractère représente 6 bits ; trois octets d'entrée (24 bits) correspondent à quatre caractères de sortie. L'alphabet n'est pas arbitraire : il évite les caractères qui diffèrent entre EBCDIC et ASCII, évitant les caractères de contrôle, les guillemets et la barre oblique inverse qui devraient s'échapper dans les littéraux de chaîne C. La variante base64url remplace le plus par un tiret et la barre oblique par un trait de soulignement pour éviter les caractères réservés dans les URL et les noms de fichiers. Les deux variantes sont également valables ; La section 2 de la RFC 4648 spécifie base64, la section 5 spécifie l'url base64, et une application doit indiquer laquelle elle utilise.

Le remplissage avec des caractères égaux amène la sortie à un multiple de quatre caractères. Si l'entrée est 1 octet (8 bits), la sortie est constituée de deux caractères plus deux signes égal. Si l'entrée est de 2 octets (16 bits), la sortie est composée de trois caractères plus un signe égal. Si l'entrée est un multiple de 3 octets, aucun remplissage n'est nécessaire. Certaines applications omettent le remplissage ou autorisent un remplissage manquant lors du décodage ; La section 3.2 de la RFC 4648 définit le codage canonique comme toujours rempli, mais la section 3.3 note que les décodeurs peuvent accepter un remplissage manquant pour des raisons de compatibilité.

Les alphabets implémentés par cet outil : Base64 et Base64url standard ; les autres bases restent en dehors de son champ d'application

La distinction de remplissage est la raison pour laquelle les implémentations ne sont pas d'accord : un décodeur strict rejette les égaux manquants, tandis qu'un décodeur indulgent l'accepte. La RFC 4648 dit explicitement : le caractère de remplissage égal est généralement codé en pourcentage lorsqu'il est utilisé dans les URL, donc si la sortie base64url est utilisée directement dans un paramètre d'URL, le remplissage n'est pas requis et doit être omis. Cette phrase est l’une des raisons pour lesquelles le mode URL sécurisé et l’omission de remplissage sont souvent associés, bien qu’il s’agisse de choix indépendants. La section 5 (base64url) n'interdit pas le remplissage ; il note simplement la pratique courante.

Un appelant qui choisit base64url doit décider si un remplissage est requis pour le système de réception. Les caractères non alphabétiques dans l'entrée sont traités différemment par différents décodeurs. La section 3.1 de la RFC 4648 déclare : Les mises en œuvre DOIVENT rejeter le codage s'il contient des caractères en dehors de l'alphabet de base. Cependant, la section 3.3 note que MIME Base64 (RFC 2045) autorise les sauts de ligne pour le retour à la ligne des caractères 76, et les décodeurs pour MIME doivent ignorer les espaces. La RFC fait la distinction entre le décodage strict (rejeter tous les caractères non alphabétiques) et le décodage compatible MIME (ignorer les espaces, rejeter les autres caractères).

Remplissage, caractères non alphabétiques et codage canonique : les sections qui expliquent la plupart des désaccords du décodeur

Une candidature doit choisir la règle à suivre ; la norme définit les deux. Base32 utilise A-Z et 2-7 (32 caractères au total), codant cinq octets d'entrée (40 bits) en huit caractères de sortie. Base32hex remplace 0-9 et a-v pour les caractères alphabétiques, utile dans les contextes où les lettres minuscules sont préférées.

Base16 est hexadécimal : 0-9 et a-f. Base32 et base32hex ont leurs propres règles de remplissage dans les sections 6 et 7, et la RFC fournit des vecteurs de test distincts pour chaque alphabet. La plupart des développeurs n'ont besoin que de base64 et de base64url ; base32, base32hex et base16 sont inclus dans la RFC par souci d'exhaustivité et pour des applications telles que les secrets TOTP (RFC 4226) et l'encodage DNS.

Choix d'application visibles dans cette implémentation : retour à la ligne, décodage de texte strict et gestion des erreurs

Les vecteurs de test dans la RFC 4648 sont la vérité terrain pour vérifier une implémentation. L'encodage des chaînes f, fo, foo, foob, fooba et foobar produit une sortie base64 spécifique : Zg==, Zm8=, Zm9v, Zm9vYg==, Zm9vYmE= et Zm9vYmFy. Une implémentation qui produit une sortie différente pour ces chaînes est incorrecte. La RFC fournit des vecteurs de test équivalents pour base32, base32hex et base16. L'outil d'encodage et de décodage Base64 inclut ces vecteurs afin que vous puissiez vérifier sa sortie par rapport à la norme. Le retour à la ligne est une préoccupation MIME, pas une préoccupation base64.

RFC 2045 spécifie les lignes de caractères 76 ; La section 3.1 de la RFC 4648 le note dans le contexte de MIME mais n'en fait pas une exigence de base64 lui-même. Certaines applications s'enroulent sur 64 caractères (la norme PEM d'origine) ; d'autres ne s'enroulent pas du tout. Un décodeur strict RFC 4648 base64 fonctionne uniquement sur l'alphabet et le remplissage. Un décodeur compatible MIME doit ignorer les sauts de ligne (CR, LF, CRLF). Une application utilisant base64 en dehors de MIME ne doit pas ajouter de sauts de ligne à moins que le système récepteur ne l'exige ; la RFC ne définit pas le retour à la ligne dans le cadre de base64.

Exemple pratique : les propres vecteurs de test de la RFC — encodant les préfixes 'foobar' et les vérifiant dans le navigateur

La gestion des espaces est un autre point de divergence dans la mise en œuvre. La RFC 4648 indique que les décodeurs stricts doivent rejeter les caractères non alphabétiques. La base64 enveloppée dans MIME (RFC 2045 base64) permet des espaces pour le formatage. Les deux normes s'accordent sur ce que devraient être les octets de sortie mais diffèrent sur quelle entrée est valide. La plupart des implémentations JavaScript choisissent la compatibilité MIME et ignorent les espaces ; la règle stricte est rarement utilisée dans les navigateurs. L'encodeur et décodeur Base64 accepte à la fois les entrées contenant des espaces (MIME) et strictes, rendant la distinction explicite. Le décodage canonique ou indulgent est le dernier écart majeur.

Le décodage canonique suit la section 4648 de la RFC 3.2 : rejeter le remplissage mal formé, rejeter le remplissage manquant, rejeter les caractères non alphabétiques. Le décodage indulgent, utilisé dans les standards Web (la spécification HTML l'appelle forgiving-base64), ajoute des règles : ignorer les espaces, accepter le remplissage manquant, autoriser les tirets et les traits de soulignement comme équivalents plus slash, même en mode base64 standard. atob() de JavaScript est indulgent ; un décodeur RFC 4648 strict est plus strict. Ni l’un ni l’autre n’a tort ; ils servent des contextes différents. Une application lisant les données d’un utilisateur ou du réseau doit savoir quelle règle attend l’autre partie.

Ce que cela ne couvre pas : les documents MIME et PEM eux-mêmes et les API spécifiques au langage

La RFC laisse neuf choix à l'application : lequel des cinq alphabets, s'il faut exiger ou autoriser le remplissage, s'il faut exiger ou autoriser les espaces, s'il faut traiter le trait de soulignement comme des équivalents de barre oblique, comment signaler les erreurs, comment gérer la fin de l'entrée, s'il faut accepter le remplissage manquant, combien d'octets de sortie allouer et comment signaler une limite de taille. Ces choix expliquent pourquoi deux implémentations de la RFC 4648 peuvent être en désaccord sur la même entrée. Lisez la RFC une fois ; vérifiez votre implémentation par rapport à ses vecteurs de test ; indiquez les options utilisées par votre application ; tester l’interopérabilité avec le homologue réel, et non avec des hypothèses.

Comprendre la RFC 4648 règle la plupart des différends Base64 car le désaccord ne porte généralement pas sur la RFC elle-même mais sur les options choisies par chaque partie. La RFC est suffisamment brève pour être lue de bout en bout en une heure. La norme définit les alphabets, fournit des vecteurs de test et avertit des domaines dans lesquels les implémentations doivent décider. L'outil d'encodage et de décodage Base64 vous permet d'expérimenter les vecteurs de test et de voir l'alphabet standard en action. La plupart des utilisations quotidiennes de base64 ne nécessitent pas de connaissances approfondies en RFC ; mais lors du débogage des incompatibilités d'encodage ou de l'intégration avec une API inconnue, la lecture de la norme une fois élimine les incertitudes.

À retenir : lisez la norme une fois – comment l'encodeur et le décodeur Base64 vous offrent un moyen rapide de vérifier les vecteurs de test de l'alphabet standard

RFC 4648 est la consolidation de décennies de pratique de codage de base ad hoc en une seule spécification lisible. Il ne définit pas quand utiliser base64 (MIME, PEM, JWT, URI de données, etc. ont chacun leurs propres spécifications) ; il définit ce qu'est base64. En définissant cinq familles de codage et en notant quelles options sont canoniques, la RFC permet de vérifier si une implémentation est correcte. Les vecteurs de test faisant autorité sont le point de départ : si votre implémentation code foobar et produit autre chose que Zm9vYmFy, la RFC indique que l'implémentation est fausse.

Utilisez cette autorité comme point de contrôle de vérification : codez chaque vecteur de test RFC, comparez les caractères exacts, puis décodez le résultat pour confirmer que les octets d'origine reviennent inchangés. Cette vérification basée sur le navigateur sépare une erreur d'alphabet ou de remplissage d'un problème ailleurs dans une intégration, tout en conservant la norme elle-même comme référence plutôt que de s'appuyer sur une étiquette de bibliothèque.