Charger un fichier
  1. base64hub
  2. Apprendre Base64
  3. Normes et RFC Base64
Référence

Normes Base64 : de PEM et MIME à la RFC 4648

Base64 n’a ni inventeur unique ni spécification unique. L’encodage est né de l’e-mail sécurisé en 1987, a été repris par MIME, puis a enfin été décrit pour lui-même en 2003. Voici les documents qui le définissent et les variantes qu’ils ont créées.

Chronologie

AnnéeDocumentApport
1987RFC 989 (PEM, partie I)L’« encodage imprimable » à 64 caractères avec le remplissage =, plus * pour les sections non chiffrées
1988, 1989RFC 1040, RFC 1113Versions révisées de PEM
1992RFC 1341 (MIME)Base64 comme Content-Transfer-Encoding pour l’e-mail
1993RFC 1421 (PEM), RFC 1521 (MIME)Lignes PEM d’exactement 64 caractères, MIME révisé
1996RFC 2045 (MIME)La définition MIME toujours en vigueur : lignes de 76 caractères au plus
1997RFC 2152 (UTF-7)Base64 au sein d’un encodage de texte pour Unicode
2003RFC 3501 (IMAP4rev1)Base64 modifié avec , pour les noms de boîtes aux lettres
2003RFC 3548Première spécification autonome : base64, base64url, base32, base16
2006RFC 4648Remplace la RFC 3548, ajoute base32hex et des vecteurs de test
2007RFC 4880 (OpenPGP)Armure Radix-64 avec une somme de contrôle CRC-24
2015RFC 7468Règles strictes pour les fichiers de certificats et de clés de type PEM
2015RFC 7515 (JWS)Base64URL sans remplissage pour les jetons
2024RFC 9580 (OpenPGP)Remplace la RFC 4880, déprécie la somme de contrôle de l’armure

PEM : là où Base64 a commencé

L’alphabet utilisé aujourd’hui apparaît pour la première fois dans la RFC 989, « Privacy Enhancement for Internet Electronic Mail », publiée en février 1987. Le courrier chiffré devait traverser des passerelles qui ne géraient que du texte imprimable : PEM avait donc besoin d’écrire un texte chiffré binaire avec des caractères capables de survivre à n’importe quel système de messagerie. Il prenait 6 bits à la fois et les faisait correspondre à A-Z, a-z, 0-9, + et /, avec = pour le remplissage. La table de la RFC 989 est identique à la table de l’alphabet de ce site. Elle réservait aussi * pour marquer les sections non chiffrées, une fonctionnalité qui n’a pas survécu.

PEM est passé par les RFC 1040 et 1113 avant de se stabiliser dans la RFC 1421 (février 1993), qui a fixé la longueur de ligne : « each line except the last containing exactly 64 printable characters and the final line containing 64 or fewer ». La raison invoquée était l’impression et la limite de 1000 caractères par ligne de SMTP. PEM en tant que système de courrier sécurisé ne s’est jamais imposé, mais son format de fichier, si. Chaque bloc -----BEGIN CERTIFICATE----- en descend, et la RFC 7468 (2015) en fixe aujourd’hui les règles : les générateurs doivent couper à exactement 64 caractères, les analyseurs peuvent accepter d’autres largeurs. Inspectez ces fichiers avec le décodeur de certificats.

MIME : Base64 pour chaque pièce jointe

MIME (RFC 1341 en 1992, RFC 1521 en 1993, RFC 2045 en 1996) avait besoin de placer des images et des documents dans des e-mails et a emprunté l’encodage de PEM. La RFC 2045 reste la référence pour l’e-mail aujourd’hui, et elle diffère de PEM sur deux points :

  • Les lignes encodées ne doivent pas dépasser 76 caractères et sont séparées par CRLF.
  • « Any characters outside of the base64 alphabet are to be ignored in base64-encoded data. » Les décodeurs sautent les sauts de ligne, les espaces et tout ce qui ne fait pas partie de l’alphabet.

C’est cette seconde règle qui explique pourquoi tant de décodeurs suppriment en silence les caractères non valides. Produisez une sortie au format MIME avec l’encodeur Base64 MIME, et consultez Base64 dans l’e-mail pour voir comment les pièces jointes sont structurées.

RFC 3548 et RFC 4648 : une seule référence pour tous

Jusqu’en 2003, chaque protocole qui utilisait Base64 renvoyait à MIME ou à PEM et héritait de leurs règles de longueur de ligne et de décodage tolérant, qu’il le veuille ou non. La RFC 3548 (juillet 2003) a défini base64, base64url, base32 et base16 comme des encodages autonomes. La RFC 4648 (octobre 2006) l’a remplacée avec des changements mineurs : elle a ajouté base32hex, qui conserve l’ordre de tri des données encodées, et une série de vecteurs de test :

BASE64("")       = ""
BASE64("f")      = "Zg=="
BASE64("fo")     = "Zm8="
BASE64("foo")    = "Zm9v"
BASE64("foobar") = "Zm9vYmFy"

Les règles de la RFC 4648 sont plus strictes que celles de MIME, sauf si la spécification qui y fait référence en décide autrement :

  • Sauts de ligne : les implémentations ne doivent pas en ajouter (section 3.1).
  • Remplissage : les implémentations doivent inclure le remplissage = (section 3.2).
  • Caractères hors alphabet : les décodeurs doivent les rejeter (section 3.3).
  • Encodage canonique : les encodeurs doivent mettre les bits inutilisés à zéro, et les décodeurs peuvent rejeter une entrée où ce n’est pas le cas (section 3.5). Sans cela, SGk/Pg== et SGk/Ph== se décodent tous les deux en Hi?>.

La formule « unless the specification referring to this document explicitly states otherwise » fait beaucoup de travail. C’est grâce à elle que JWS peut abandonner le remplissage et que MIME garde ses lignes de 76 caractères, alors que les deux utilisent « le Base64 de la RFC 4648 ». Les outils Base32 et Base16 implémentent les deux autres encodages de la même RFC.

Variantes définies dans d’autres normes

JWS et JWT : Base64URL sans remplissage

La RFC 7515 (mai 2015) définit BASE64URL(x) comme l’alphabet de la section 5 « with all trailing ‘=’ characters omitted », sans sauts de ligne ni espaces. JWT, JWE, JWK et la plupart de la famille JOSE l’utilisent. Détails dans Base64 dans les JWT.

IMAP : UTF-7 modifié avec une virgule

Les noms de boîtes aux lettres IMAP sont des chaînes 7 bits ; la RFC 3501 (section 5.1.3) encode donc les noms de dossiers non ASCII en « UTF-7 modifié ». Les suites de caractères non ASCII sont converties en UTF-16, encodées en Base64 sans remplissage, avec , au lieu de /, puis encadrées par & et -. L’exemple de la RFC elle-même, &U,BTFw-, est le nom chinois 台北, et un dossier allemand Entwürfe devient Entw&APw-rfe. L’UTF-7 classique (RFC 2152) écrit le même nom Entw+APw-rfe.

OpenPGP : Radix-64 avec un CRC-24

L’armure ASCII d’OpenPGP, c’est du Base64 MIME plus une ligne de somme de contrôle. La RFC 4880 définit un CRC-24 (polynôme générateur 0x864CFB, valeur initiale 0xB704CE) calculé sur les données binaires, encodé en Base64 et précédé de =. Voici ce que GnuPG produit pour les 12 octets Hello world! :

-----BEGIN PGP ARMORED FILE-----
Comment: Use "gpg --dearmor" for unpacking

SGVsbG8gd29ybGQh
=s4Gu
-----END PGP ARMORED FILE-----

La RFC 4880 autorise des lignes de 76 caractères au plus ; GnuPG en écrit 64. La RFC 9580 (juillet 2024) conserve le format, mais précise que la ligne CRC-24 « SHOULD NOT be generated » et que les implémentations ne doivent pas rejeter un bloc parce qu’elle est absente ou fausse.

Tableau des variantes de Base64

VarianteIndex 62 et 63RemplissageLongueur de ligneDéfinie dans
Base64 standard+ /ObligatoireAucuneRFC 4648, section 4
Base64URL- _Facultatif, selon la spécification de référenceAucuneRFC 4648, section 5
JWS / JWT- _JamaisAucuneRFC 7515
MIME+ /Obligatoire76 au plus, CRLFRFC 2045
PEM+ /ObligatoireExactement 64RFC 1421, RFC 7468
Armure OpenPGP+ /Obligatoire76 au plus (GnuPG : 64)RFC 4880, RFC 9580
UTF-7+ /AucunSans objetRFC 2152
UTF-7 modifié d’IMAP+ ,AucunSans objetRFC 3501
bcryptAlphabet ./A-Za-z0-9AucunSans objetDe facto (OpenBSD)
Hachages crypt(3)Alphabet ./0-9A-Za-zAucunSans objetDe facto (Unix)

Dans les deux dernières lignes, c’est tout l’alphabet qui est réordonné. Elles sont traitées sur la page de l’alphabet. Beaucoup d’autres formats renvoient à l’une des lignes ci-dessus sans rien changer : l’authentification HTTP Basic (RFC 7617), les data URI (RFC 2397), le type base64Binary de XML Schema et les hachages Subresource Integrity utilisent tous le Base64 standard avec remplissage.

FAQ

Quelle RFC définit Base64 ?

La RFC 4648 (octobre 2006) est la référence générale. Elle définit base64, base64url, base32, base32hex et base16. La version de MIME se trouve dans la RFC 2045, et l’original de PEM dans la RFC 1421.

Pourquoi les lignes MIME font-elles 76 caractères et les lignes PEM 64 ?

Les deux limites gardent les lignes bien en dessous de la limite de 1000 caractères de SMTP. PEM a fixé 64 dans la RFC 1421 ; MIME a choisi « pas plus de 76 » dans sa propre spécification. La RFC 4648 dit que les encodeurs ne doivent ajouter aucun saut de ligne, sauf si la norme qui y fait référence le demande.

Base64URL est-il une norme officielle ?

Oui. C’est la section 5 de la RFC 4648, « Base 64 Encoding with URL and Filename Safe Alphabet », apparue d’abord dans la RFC 3548. JWS (RFC 7515) l’utilise sans remplissage.

Qu'est-ce que la ligne =XXXX à la fin d'un bloc PGP ?

Une somme de contrôle CRC-24 des données décodées, elle-même écrite en Base64. La RFC 9580 (2024) dit que les nouvelles implémentations ne devraient plus la produire et ne doivent pas rejeter un bloc à cause d’elle.

Continuer la lecture