Message d’erreur
java.lang.IllegalArgumentException: Illegal base64 character 2d
Également affiché sous la forme
- java.lang.IllegalArgumentException: Illegal base64 character a
- java.lang.IllegalArgumentException: Illegal base64 character d
- java.lang.IllegalArgumentException: Illegal base64 character 5f
- java.lang.IllegalArgumentException: Illegal base64 character 20
La valeur hexadécimale désigne le caractère fautif : `2d` « - », `5f` « _ », `a` LF, `d` CR, `20` espace.
Java (JDK) — java.util.Base64.Decoder.decode
Ce que cela signifie
`Base64.getDecoder()` est le décodeur RFC 4648 strict : il n’accepte que `A–Z a–z 0–9 + /` et le remplissage `=`, et s’arrête au premier autre caractère. Le nombre hexadécimal est le code de ce caractère : `2d` est `-` (les tirets de `-----BEGIN …-----`, ou l’alphabet base64url), `a` un saut de ligne, `d` un retour chariot, `20` un espace, `5f` un trait de soulignement. Les données sont généralement correctes : elles sont simplement dans un autre habillage textuel que celui attendu par le décodeur.
Pourquoi cela se produit
Les lignes d’en-tête et de fin PEM n’ont pas été retirées (2d)
fréquenteLe décodage du fichier PEM entier bute sur le premier `-` de `-----BEGIN`. Seul le corps situé entre les lignes d’armure est en base64.
Sauts de ligne dans le corps (a ou d)
fréquentePEM coupe le base64 à 64 caractères par ligne. Le décodeur de base rejette le saut de ligne ; les fichiers modifiés sous Windows ajoutent en plus `\r`.
Données base64url passées au décodeur de base (2d ou 5f)
fréquenteLes segments de JWT et les coordonnées de JWK utilisent `-` et `_` au lieu de `+` et `/`. Ils nécessitent `Base64.getUrlDecoder()`.
Espaces ou guillemets venus de la configuration (20, 22)
occasionnelleLes clés collées dans du YAML, des fichiers properties ou des variables d’environnement peuvent récupérer des espaces, des guillemets ou des séquences `\n` échappées.
Comment corriger l’erreur
- 1.
Retirer l’armure et utiliser le décodeur MIME
`Base64.getMimeDecoder()` ignore les séparateurs de ligne, ce qui est exactement ce dont les corps PEM ont besoin.
java String body = pem.replaceAll("-----(BEGIN|END) [A-Z ]+-----", ""); byte[] der = Base64.getMimeDecoder().decode(body); // ignores line separators and other non-alphabet characters - 2.
Utiliser le décodeur URL pour les données JOSE
Tout le contenu d’un JWT et d’une JWK est en base64url ; le décodeur URL accepte en outre l’absence de remplissage.
java // JWT segments and JWK fields ("x", "y", "n", "e") use base64url without padding. byte[] header = Base64.getUrlDecoder().decode(jwt.split("\\.")[0]); byte[] x = Base64.getUrlDecoder().decode(jwk.get("x"));