Encodage Base64 en Java — Exemples java.util.Base64

·Java Security & API Engineer·Révisé parPavel Novak·Publié

Utilisez le Encodeur Base64 en Ligne gratuit directement dans votre navigateur — sans installation.

Essayer Encodeur Base64 en Ligne en ligne →

Chaque fois que je configure un en-tête HTTP Basic Auth, que j'intègre un certificat dans un secret Kubernetes, ou que j'envoie des données binaires via une API JSON, la première étape est toujours la même : encoder en Base64 les bytes bruts en une chaîne compatible ASCII. Java simplifie cette opération avec java.util.Base64, l'API standard disponible depuis Java 8 qui a remplacé le sun.misc.BASE64Encoder déprécié. Pour un encodage ponctuel sans écrire de code, l'encodeur Base64 de ToolDeck le fait instantanément dans le navigateur. Ce guide couvre Base64.getEncoder(), getUrlEncoder(), getMimeEncoder(), l'encodage de fichiers, le streaming avec wrap(OutputStream), et les erreurs qui piègent même les développeurs Java expérimentés. Tous les exemples compilent sur Java 8 à Java 21+.

  • Base64.getEncoder().encodeToString(bytes) est le one-liner standard — intégré au JDK depuis Java 8, inchangé jusqu'à Java 17 et 21.
  • Passez toujours StandardCharsets.UTF_8 à String.getBytes() avant l'encodage — l'omettre utilise le défaut de la plateforme, qui varie selon les JVM.
  • getUrlEncoder() produit une sortie URL-safe (- à la place de +, _ à la place de /) et withoutPadding() supprime les caractères = finaux.
  • getMimeEncoder() insère des sauts de ligne toutes les 76 caractères — requis par les formats email (MIME) et les certificats PEM.
  • Pour les fichiers volumineux, utilisez Base64.getEncoder().wrap(OutputStream) pour streamer sans charger l'intégralité du fichier en mémoire.

Qu'est-ce que l'encodage Base64 ?

Base64 convertit des données binaires arbitraires en une chaîne composée de 64 caractères ASCII imprimables : A-Z, a-z, 0-9, + et /. Chaque groupe de 3 bytes en entrée produit exactement 4 caractères Base64. Si la longueur de l'entrée n'est pas un multiple de 3, un ou deux caractères de rembourrage = sont ajoutés. La sortie encodée est toujours environ 33 % plus volumineuse que les données d'origine.

Base64 n'est pasdu chiffrement. Toute personne disposant de la chaîne encodée peut la décoder. Son but est la sécurité du transport : les en-têtes HTTP, les payloads JSON, les documents XML et les corps d'email sont des protocoles textuels qui ne peuvent pas transporter des bytes binaires bruts sans corruption. Les cas d'usage Java courants incluent l'authentification HTTP Basic, l'intégration de certificats PEM, le stockage de données binaires dans des colonnes texte de base de données, et la construction de segments de tokens JWT.

Before · text
After · text
deploy-svc:sk_live_4eC39HqLyjWDarjtT1zdp7dc
ZGVwbG95LXN2Yzpza19saXZlXzRlQzM5SHFMeWpXRGFyanRUMXpkcDdkYw==

Base64.getEncoder().encodeToString() — L'API standard

java.util.Base64 a été introduit en Java 8 comme remplacement officiel de sun.misc.BASE64Encoder. La classe fournit trois méthodes factory statiques — chacune retournant une instance de la classe imbriquée Base64.Encoder — couvrant les trois variantes Base64 définies dans la RFC 4648. Aucune bibliothèque tierce n'est nécessaire. Aucune dépendance Maven. Il suffit d'importer et d'appeler.

Exemple minimal — Encoder une String

Java 8+
import java.util.Base64;
import java.nio.charset.StandardCharsets;

public class EncodeDemo {
    public static void main(String[] args) {
        String credentials = "monitoring-svc:9f2a7c4e-b1d8-4a3f";
        byte[] credentialBytes = credentials.getBytes(StandardCharsets.UTF_8);

        String encoded = Base64.getEncoder().encodeToString(credentialBytes);
        System.out.println(encoded);
        // bW9uaXRvcmluZy1zdmM6OWYyYTdjNGUtYjFkOC00YTNm
    }
}

L'étape clé que la plupart des développeurs Java ratent la première fois : une String doit être convertie en byte[] avant l'encodage. Base64 opère sur des bytes, pas sur des caractères. encodeToString() accepte un byte[] et retourne directement la String Base64. Si tu as besoin du résultat encodé sous forme de bytes, utilise encode(byte[]) — cette méthode retourne un byte[] des caractères Base64 encodés en ASCII, utile quand tu écris directement dans un OutputStream ou construis des trames de protocole binaire.

HTTP Basic Auth — Le cas d'usage le plus courant

L'authentification HTTP Basic est probablement la raison la plus fréquente pour laquelle les développeurs Java utilisent l'encodage Base64. La spécification (RFC 7617) exige que la chaîne de credentials username:password soit encodée en Base64 et placée dans l'en-tête Authorization. J'ai vu cette opération mal réalisée plus de fois que je ne peux en compter — généralement en oubliant le séparateur deux-points ou en encodant les composants séparément.

Java — en-tête HTTP Basic Auth
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Base64;
import java.nio.charset.StandardCharsets;

public class BasicAuthExample {
    public static void main(String[] args) throws Exception {
        String username = "metrics-exporter";
        String apiKey = "sk_live_4eC39HqLyjWDarjtT1zdp7dc";

        // username:password → Base64
        String credentials = username + ":" + apiKey;
        String authHeader = "Basic " + Base64.getEncoder()
            .encodeToString(credentials.getBytes(StandardCharsets.UTF_8));

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.example.com/v2/metrics"))
            .header("Authorization", authHeader)
            .build();

        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());

        System.out.println(response.statusCode());  // 200
    }
}

Aller-retour — Encoder et décoder

Java 8+ — aller-retour encode et decode
import java.util.Base64;
import java.nio.charset.StandardCharsets;

public class RoundTrip {
    public static void main(String[] args) {
        String original = "X-Correlation-ID: req_8a4f2c91-e7b3-4d56-9012-3f7a8b9c0d1e";

        // Encodage
        String encoded = Base64.getEncoder()
            .encodeToString(original.getBytes(StandardCharsets.UTF_8));
        System.out.println(encoded);
        // WC1Db3JyZWxhdGlvbi1JRDogcmVxXzhhNGYyYzkxLWU3YjMtNGQ1Ni05MDEyLTNmN2E4YjljMGQxZQ==

        // Décodage
        byte[] decodedBytes = Base64.getDecoder().decode(encoded);
        String decoded = new String(decodedBytes, StandardCharsets.UTF_8);

        System.out.println(original.equals(decoded));  // true
    }
}
Remarque :L'API java.util.Base64est identique de Java 8 à Java 17 et Java 21. Aucune migration n'est nécessaire lors d'une mise à jour de JDK. Le même code compile et s'exécute sur toute version depuis Java 8.

Encoder des données non-String — byte[], UUID et timestamps

L'encodage Base64 en Java commence toujours par un byte[]. Les Strings se convertissent via getBytes(StandardCharsets.UTF_8), mais d'autres types nécessitent une étape de conversion préalable. Les UUIDs, timestamps et identifiants numériques doivent être sérialisés en une représentation String ou bytes avant de pouvoir être encodés en Base64.

UUID — Encoder sous forme de représentation String

Java — encodage Base64 d'un UUID
import java.util.Base64;
import java.util.UUID;
import java.nio.charset.StandardCharsets;

UUID sessionId = UUID.fromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8");
String encoded = Base64.getEncoder()
    .encodeToString(sessionId.toString().getBytes(StandardCharsets.UTF_8));
System.out.println(encoded);
// NmJhN2I4MTAtOWRhZC0xMWQxLTgwYjQtMDBjMDRmZDQzMGM4

UUID compact — Encoder les 16 bytes bruts

Pour un résultat encodé plus court, extrais les 128 bits du UUID sous forme de 16 bytes bruts plutôt que de le convertir en sa forme String de 36 caractères. La sortie Base64 passe de 48 à 24 caractères.

Java — encodage UUID compact
import java.nio.ByteBuffer;
import java.util.Base64;
import java.util.UUID;

UUID eventId = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");

ByteBuffer buffer = ByteBuffer.wrap(new byte[16]);
buffer.putLong(eventId.getMostSignificantBits());
buffer.putLong(eventId.getLeastSignificantBits());

String compact = Base64.getUrlEncoder()
    .withoutPadding()
    .encodeToString(buffer.array());
System.out.println(compact);
// VQ6EAOKbQdSnFkRmVUQAAA
// 22 chars contre 48 pour l'approche basée sur String

Timestamp et payload mixte

Java — encodage d'un payload JSON-like avec timestamp
import java.time.Instant;
import java.util.Base64;
import java.nio.charset.StandardCharsets;

// Simulation d'un payload de style JWT
String payload = String.format(
    "{"sub":"usr_7b3c","iss":"auth.internal","iat":%d,"exp":%d}",
    Instant.now().getEpochSecond(),
    Instant.now().plusSeconds(3600).getEpochSecond()
);

String encoded = Base64.getUrlEncoder()
    .withoutPadding()
    .encodeToString(payload.getBytes(StandardCharsets.UTF_8));
System.out.println(encoded);
// eyJzdWIiOiJ1c3JfN2IzYyIsImlzcyI6ImF1dGguaW50ZXJuYWwiLCJpYXQiOj... (URL-safe, sans rembourrage)
Avertissement :N'appelez pas toString() sur un byte[]en espérant obtenir son contenu — cela retourne le hash d'identité du tableau, de la forme [B@6d06d69c. Utilisez new String(bytes, StandardCharsets.UTF_8) ou passez le tableau de bytes directement à encodeToString().

Référence des méthodes Base64.Encoder

La classe java.util.Base64 expose trois méthodes factory, chacune retournant un Base64.Encoder configuré pour une variante spécifique. Les instances d'encodeur sont thread-safe et sans état — créez-les une fois et réutilisez-les.

Méthode
Type
Description
getEncoder()
Base64.Encoder
Retourne un encodeur RFC 4648 standard utilisant l'alphabet de base (A-Z, a-z, 0-9, +, /)
getUrlEncoder()
Base64.Encoder
Retourne un encodeur utilisant l'alphabet URL-safe (- à la place de +, _ à la place de /)
getMimeEncoder()
Base64.Encoder
Retourne un encodeur MIME qui insère des sauts de ligne \r\n toutes les 76 caractères
getMimeEncoder(lineLength, lineSeparator)
Base64.Encoder
Encodeur MIME avec longueur de ligne et séparateur personnalisés
encoder.withoutPadding()
Base64.Encoder
Retourne un encodeur qui omet les caractères de rembourrage = finaux
encoder.encode(byte[])
byte[]
Encode un tableau de bytes, retourne un tableau de bytes encodé
encoder.encodeToString(byte[])
String
Encode un tableau de bytes, retourne directement une String encodée
encoder.wrap(OutputStream)
OutputStream
Enveloppe un OutputStream pour l'encodage Base64 en streaming

Base64.getUrlEncoder() — Encodage URL-safe

L'encodeur URL-safe utilise un alphabet alternatif où + devient - et / devient _, tel que défini dans la RFC 4648 Section 5. C'est important dès que la chaîne Base64 apparaît dans un paramètre de requête URL, un nom de fichier, ou une valeur de cookie — les caractères Base64 standard entrent en conflit avec les délimiteurs URL et les caractères réservés du système de fichiers.

Java — encodage Base64 URL-safe
import java.util.Base64;
import java.nio.charset.StandardCharsets;

String redirectUri = "https://app.internal/callback?state=auth_pending&nonce=9f2a7c";
byte[] data = redirectUri.getBytes(StandardCharsets.UTF_8);

// Encodeur standard — contient + et / qui cassent les URLs
String standard = Base64.getEncoder().encodeToString(data);
System.out.println(standard);
// aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s/c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw==

// Encodeur URL-safe — sûr pour les paramètres de requête et noms de fichiers
String urlSafe = Base64.getUrlEncoder().encodeToString(data);
System.out.println(urlSafe);
// aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s_c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw==

// URL-safe sans rembourrage — pour les JWTs et tokens compacts
String noPadding = Base64.getUrlEncoder().withoutPadding().encodeToString(data);
System.out.println(noPadding);
// aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s_c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw

La variante withoutPadding() supprime les caractères = finaux. Les spécifications JWT exigent du Base64 URL-safe sans rembourrage pour les segments d'en-tête et de payload, donc getUrlEncoder().withoutPadding() est précisément l'appel à utiliser lors de la construction ou manipulation manuelle de tokens JWT.

Remarque :La méthode withoutPadding()retourne une nouvelle instance d'encodeur — elle ne modifie pas l'original. Les deux peuvent être assignés à des champs static final et réutilisés sans risque entre threads.

Encoder depuis un fichier et une réponse API

Les deux scénarios réels les plus courants pour l'encodage Base64 en Java : lire un fichier binaire depuis le disque (certificats, images, bundles de configuration) et encoder des données reçues d'une réponse HTTP.

Encoder un fichier en Base64

Java — encodage d'un fichier
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;

public class FileEncoder {
    public static void main(String[] args) {
        try {
            byte[] fileBytes = Files.readAllBytes(Path.of("certs/server.pem"));
            String encoded = Base64.getEncoder().encodeToString(fileBytes);

            System.out.printf("Original : %d bytes%n", fileBytes.length);
            System.out.printf("Encodé :   %d chars%n", encoded.length());

            // Écriture du contenu encodé dans un fichier texte
            Files.writeString(
                Path.of("certs/server.pem.b64"),
                encoded
            );
        } catch (java.io.IOException e) {
            System.err.println("Échec de lecture du fichier : " + e.getMessage());
        }
    }
}

Encoder le corps d'une réponse API

Java 11+ — encodage d'une réponse HTTP
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Base64;

public class ApiEncoder {
    public static void main(String[] args) {
        try {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://api.example.com/v2/reports/weekly.pdf"))
                .header("Authorization", "Bearer tok_8f2a9c3d")
                .build();

            HttpResponse<byte[]> response = client.send(
                request, HttpResponse.BodyHandlers.ofByteArray()
            );

            if (response.statusCode() == 200) {
                String encoded = Base64.getEncoder()
                    .encodeToString(response.body());
                System.out.printf("Encodé %d bytes → %d chars%n",
                    response.body().length, encoded.length());
            } else {
                System.err.printf("HTTP %d : %s%n",
                    response.statusCode(),
                    new String(response.body()));
            }
        } catch (Exception e) {
            System.err.println("Requête échouée : " + e.getMessage());
        }
    }
}

Note rapide avant la section CLI : si tu as juste besoin de coller un fichier ou une réponse API et d'obtenir la sortie Base64 sans écrire de code, l' encodeur Base64 en ligne gère aussi bien le texte que les données binaires.

Encodage Base64 en ligne de commande

Parfois il suffit d'encoder une chaîne ou un fichier depuis le terminal — sans projet Java, sans IDE, sans étape de build. La plupart des systèmes Unix embarquent une commande base64, et si tu as un JDK installé, tu peux utiliser jshell pour une approche native Java.

Bash — encodage Base64 en ligne de commande
# macOS / Linux — encoder une chaîne
echo -n "deploy-bot:sk_prod_9f2a7c4e" | base64
# ZGVwbG95LWJvdDpza19wcm9kXzlmMmE3YzRl

# Encoder un fichier
base64 < certs/server.pem > certs/server.pem.b64

# Avec jshell (JDK 9+)
echo 'System.out.println(java.util.Base64.getEncoder().encodeToString("deploy-bot:sk_prod_9f2a7c4e".getBytes()))' | jshell -

# Avec java directement en one-liner
java -e 'System.out.println(java.util.Base64.getEncoder().encodeToString(args[0].getBytes()))' "my-secret"
# Note : java -e nécessite JDK 23+ (JEP 477)

L'approche jshell est particulièrement utile pour vérifier que ton code Java produit la même sortie qu'un outil Unix, ou pour déboguer une divergence entre ce que ton service envoie et ce que le destinataire attend. J'ai un alias shell pour ça.

Remarque :Sur macOS, la commande base64 utilise -D pour le décodage. Sur Linux (GNU coreutils), elle utilise -d. Le comportement d'encodage est identique sur les deux. L'option -w 0sur Linux désactive le retour à la ligne dans la sortie, ce qui est généralement souhaitable lors d'un pipe vers d'autres commandes.

Apache Commons Codec — Alternative haute performance

Pour la plupart des applications, java.util.Base64 est suffisamment rapide. Mais si tu traites des millions d'opérations d'encodage dans une boucle intensive — pipelines d'ingestion de logs ou brokers de messages à haut débit — Apache Commons Codec vaut la peine d'être évalué. Il existe depuis bien avant Java 8 et offre une alternative éprouvée avec une surface d'API légèrement différente.

Java — Apache Commons Codec
// Maven: org.apache.commons:commons-codec:1.17.0
import org.apache.commons.codec.binary.Base64;
import java.nio.charset.StandardCharsets;

byte[] telemetryPayload = ("{"service":"metrics-collector","
    + ""host":"prod-east-07","
    + ""cpu_pct":72.4,"
    + ""mem_mb":3891,"
    + ""timestamp":1710523200}")
    .getBytes(StandardCharsets.UTF_8);

// Encodage standard
String encoded = Base64.encodeBase64String(telemetryPayload);

// Encodage URL-safe
String urlSafe = Base64.encodeBase64URLSafeString(telemetryPayload);

// Vérifier si une chaîne est du Base64 valide
boolean valid = Base64.isBase64(encoded);
System.out.println(valid);  // true

Apache Commons Codec fournit également Base64OutputStream et Base64InputStream pour les scénarios de streaming, et inclut une méthode de validation absente de l'encodeur JDK. Si Commons Codec est déjà dans ton arbre de dépendances (il est embarqué dans de nombreux projets Apache), rien n'empêche de l'utiliser.

Guava BaseEncoding

La bibliothèque Guava de Google inclut BaseEncoding qui propose une API fluente pour Base64 avec des séparateurs de ligne configurables, le contrôle du rembourrage, et le support des alphabets standard et URL-safe. L'API se lit clairement, mais ajouter Guava (environ 3 Mo) uniquement pour l'encodage Base64 est excessif. Si Guava est déjà dans ton projet pour ses collections ou utilitaires de cache, l'API d'encodage est un bonus appréciable.

Java — Guava BaseEncoding
// Maven: com.google.guava:guava:33.1.0-jre
import com.google.common.io.BaseEncoding;
import java.nio.charset.StandardCharsets;

byte[] webhookPayload = ("{"event":"deployment.completed","
    + ""repo":"payments-api","
    + ""sha":"a7f2c91e4b3d","
    + ""environment":"production"}")
    .getBytes(StandardCharsets.UTF_8);

// Base64 standard
String standard = BaseEncoding.base64().encode(webhookPayload);

// URL-safe
String urlSafe = BaseEncoding.base64Url().encode(webhookPayload);

// Sans rembourrage
String noPad = BaseEncoding.base64Url().omitPadding().encode(webhookPayload);

// Avec séparateurs de ligne (style PEM)
String wrapped = BaseEncoding.base64()
    .withSeparator("\n", 64)
    .encode(webhookPayload);

Base64.getMimeEncoder() — Sortie MIME et PEM avec retours à la ligne

L'encodeur MIME insère des sauts de ligne \r\n toutes les 76 caractères, conformément à la spécification MIME (RFC 2045). Les certificats PEM, les pièces jointes S/MIME et certaines API legacy attendent ce format. Les encodeurs standard et URL-safe produisent une seule ligne continue — si tu passes leur sortie à un système attendant du Base64 avec retours à la ligne, il peut échouer silencieusement ou rejeter les données.

Java — encodage Base64 MIME
import java.util.Base64;
import java.nio.charset.StandardCharsets;

// Simulation d'un corps de certificat PEM
byte[] certData = new byte[256];  // En pratique, lire depuis un fichier .der
new java.security.SecureRandom().nextBytes(certData);

// Encodeur MIME par défaut — 76 chars par ligne, séparateur \r\n
String mimeEncoded = Base64.getMimeEncoder().encodeToString(certData);
System.out.println(mimeEncoded);
// QYx2K3p8Xg7JmN1R+wFkLd...  (76 chars)
// Ht5Bv9CzAq0PnSjYl8WxUe...  (76 chars)
// ...

// Encodeur MIME personnalisé — 64 chars par ligne (standard PEM), séparateur \n
Base64.Encoder pemEncoder = Base64.getMimeEncoder(64, new byte[]{'\n'});
String pemBody = pemEncoder.encodeToString(certData);
System.out.println("-----BEGIN CERTIFICATE-----");
System.out.println(pemBody);
System.out.println("-----END CERTIFICATE-----");
Avertissement :N'utilisez pas getMimeEncoder() pour les tokens JWT, les en-têtes HTTP ou les paramètres URL. Les sauts de ligne corrompront les données dans ces contextes. Utilisez getEncoder() ou getUrlEncoder() à la place.

Streaming de fichiers volumineux avec Base64.getEncoder().wrap()

Charger un fichier entier dans un byte[] avec Files.readAllBytes() fonctionne pour les petits fichiers, mais au-delà de 50-100 Mo tu risques une OutOfMemoryError. Le JDK fournit Base64.getEncoder().wrap(OutputStream), qui retourne un OutputStream encodant les données à la volée lors de l'écriture. Les bytes encodés sont transmis au flux sous-jacent sans mettre l'intégralité de l'entrée en mémoire tampon.

Java — encodage Base64 en streaming
import java.io.*;
import java.nio.file.*;
import java.util.Base64;

public class StreamingEncoder {
    public static void main(String[] args) throws IOException {
        Path inputPath = Path.of("backups/database-export.sql.gz");
        Path outputPath = Path.of("backups/database-export.sql.gz.b64");

        try (
            InputStream in = Files.newInputStream(inputPath);
            OutputStream fileOut = Files.newOutputStream(outputPath);
            OutputStream base64Out = Base64.getEncoder().wrap(fileOut)
        ) {
            byte[] buffer = new byte[8192];
            int bytesRead;
            long totalBytes = 0;

            while ((bytesRead = in.read(buffer)) != -1) {
                base64Out.write(buffer, 0, bytesRead);
                totalBytes += bytesRead;
            }

            System.out.printf("Streamé %d bytes via l'encodeur Base64%n", totalBytes);
        }
        // La fermeture de base64Out vide automatiquement les bytes de rembourrage finaux
    }
}

Le bloc try-with-resources gère le vidage et la fermeture. Un détail qui piège souvent : le rembourrage Base64 final n'est écrit que lors de la fermeture du OutputStream enveloppant. Si tu oublies de le fermer (ou ne fermes que le flux externe), les derniers caractères de ta sortie encodée peuvent être manquants.

Streaming vers un socket réseau

La méthode wrap() fonctionne avec n'importe quel OutputStream — sortie fichier, sortie socket, corps de réponse HTTP, et même ByteArrayOutputStream. Voici un exemple d'écriture de données encodées en Base64 directement dans un buffer en mémoire, utile pour les tests unitaires ou la construction de payloads à envoyer via HTTP :

Java — streaming vers ByteArrayOutputStream
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.Base64;
import java.nio.charset.StandardCharsets;

ByteArrayOutputStream buffer = new ByteArrayOutputStream();

try (OutputStream encoder = Base64.getEncoder().wrap(buffer)) {
    // Écriture en morceaux — simule la lecture depuis un flux
    encoder.write("chunk-1:telemetry-data-".getBytes(StandardCharsets.UTF_8));
    encoder.write("chunk-2:more-payload-".getBytes(StandardCharsets.UTF_8));
    encoder.write("chunk-3:final-segment".getBytes(StandardCharsets.UTF_8));
}

String encoded = buffer.toString(StandardCharsets.UTF_8);
System.out.println(encoded);
// Y2h1bmstMTp0ZWxlbWV0cnktZGF0YS1jaHVuay0yOm1vcmUtcGF5bG9hZC1jaHVuay0zOmZpbmFsLXNlZ21lbnQ=

// Vérification de l'aller-retour
byte[] decoded = Base64.getDecoder().decode(encoded);
System.out.println(new String(decoded, StandardCharsets.UTF_8));
// chunk-1:telemetry-data-chunk-2:more-payload-chunk-3:final-segment
Remarque :La taille du buffer dans l'exemple de streaming (8192 bytes) n'est pas arbitraire. Elle correspond à la taille de buffer par défaut utilisée par BufferedInputStreamet constitue un bon équilibre entre utilisation mémoire et surcharge des appels système. Des buffers plus petits augmentent le nombre d'appels lecture/écriture ; des buffers plus grands gaspillent la mémoire sans amélioration significative du débit.

Instances d'encodeur thread-safe — Stocker et réutiliser

Le Base64.Encoder retourné par les méthodes factory est immuable et thread-safe. Appeler Base64.getEncoder() à chaque opération d'encodage crée un nouvel objet à chaque fois. La JVM optimisera probablement cela, mais stocker l'encodeur dans un champ static final rend l'intention explicite et évite des allocations inutiles dans les chemins critiques.

Java — instances d'encodeur réutilisables
import java.util.Base64;
import java.nio.charset.StandardCharsets;

public class TokenService {
    // Créer une fois, réutiliser partout — thread-safe
    private static final Base64.Encoder STANDARD = Base64.getEncoder();
    private static final Base64.Encoder URL_SAFE = Base64.getUrlEncoder().withoutPadding();
    private static final Base64.Encoder MIME = Base64.getMimeEncoder();

    public static String encodeForHeader(String value) {
        return STANDARD.encodeToString(value.getBytes(StandardCharsets.UTF_8));
    }

    public static String encodeForUrl(byte[] data) {
        return URL_SAFE.encodeToString(data);
    }

    public static String encodeForEmail(byte[] attachment) {
        return MIME.encodeToString(attachment);
    }
}

Ce pattern est particulièrement utile dans les services Spring Boot où une classe utilitaire gère l'encodage pour plusieurs contrôleurs ou méthodes de service. L'appel à withoutPadding() retourne une nouvelle instance d'encodeur, tu peux donc stocker les variantes avec et sans rembourrage comme champs séparés. Chaque appel à encodeToString() ou encode() est sans état — aucune synchronisation nécessaire, aucun état mutable partagé.

Erreurs courantes

Appeler getBytes() sans spécifier de charset

Problème : String.getBytes() sans argument de charset utilise l'encodage par défaut de la plateforme, qui est windows-1252 sous Windows, UTF-8 sur la plupart des systèmes Linux, et variable sous macOS. Le même code produit des sorties Base64 différentes selon les machines.

Solution : Passez toujours StandardCharsets.UTF_8 explicitement.

Before · Java
After · Java
String text = "Clé d'accès : prod-east";
byte[] bytes = text.getBytes();  // défaut plateforme — imprévisible
String encoded = Base64.getEncoder().encodeToString(bytes);
String text = "Clé d'accès : prod-east";
byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
String encoded = Base64.getEncoder().encodeToString(bytes);
Utiliser l'encodeur standard pour des paramètres URL

Problème : Base64.getEncoder() produit des caractères + et /. Placés dans une chaîne de requête URL, + est interprété comme un espace et / comme un séparateur de chemin, corrompant silencieusement la valeur côté récepteur.

Solution : Utilisez Base64.getUrlEncoder() pour toute valeur qui apparaîtra dans une URL.

Before · Java
After · Java
// Token dans un paramètre de requête URL — va se casser
String token = Base64.getEncoder()
    .encodeToString(sessionData);
String url = "https://auth.internal/verify?token=" + token;
// Encodage URL-safe — pas de + ni /
String token = Base64.getUrlEncoder()
    .withoutPadding()
    .encodeToString(sessionData);
String url = "https://auth.internal/verify?token=" + token;
Décoder avec la mauvaise variante d'encodeur

Problème : Encoder avec getUrlEncoder() et décoder avec getDecoder() (ou vice versa) lève une IllegalArgumentException car - et _ ne sont pas valides dans l'alphabet Base64 standard, et + et / ne sont pas valides dans l'alphabet URL-safe.

Solution : Décodez toujours avec le décodeur correspondant : getUrlDecoder() pour l'URL-safe, getDecoder() pour le standard.

Before · Java
After · Java
String encoded = Base64.getUrlEncoder()
    .encodeToString(data);
// Plus tard...
byte[] decoded = Base64.getDecoder()  // MAUVAIS décodeur
    .decode(encoded);
// IllegalArgumentException si encoded contient - ou _
String encoded = Base64.getUrlEncoder()
    .encodeToString(data);
// Plus tard...
byte[] decoded = Base64.getUrlDecoder()  // décodeur correspondant
    .decode(encoded);
Ne pas fermer l'OutputStream wrap()

Problème : L'encodeur en streaming met en tampon jusqu'à 2 bytes d'entrée en attente d'un groupe complet de 3 bytes. Si tu ne fermes pas l'OutputStream enveloppant, les 1 à 4 derniers caractères Base64 (dont le rembourrage) ne sont jamais écrits.

Solution : Utilise try-with-resources, ou appelle close() explicitement sur le flux enveloppé avant de lire la sortie.

Before · Java
After · Java
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream b64os = Base64.getEncoder().wrap(baos);
b64os.write(data);
// baos.toString() est INCOMPLET — bytes finaux manquants
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (OutputStream b64os = Base64.getEncoder().wrap(baos)) {
    b64os.write(data);
}  // close() vide le rembourrage final
String encoded = baos.toString();  // complet

Méthodes d'encodage Base64 — Comparaison

Méthode
URL-Safe
Streaming
Sauts de ligne
Types personnalisés
Installation requise
Base64.getEncoder()
✓ (wrap)
Non (JDK 8+)
Base64.getUrlEncoder()
✓ (wrap)
Non (JDK 8+)
Base64.getMimeEncoder()
✓ (wrap)
✓ (76 chars)
Non (JDK 8+)
Apache Commons Codec
Dépendance Maven
Guava BaseEncoding
✓ (configurable)
Dépendance Maven
jcmd / CLI base64
✓ (pipe)
N/A
Installation système

Pour la plupart des projets : java.util.Base64 est le bon choix. Zéro dépendance, intégré au JDK, thread-safe, et couvre les trois variantes RFC 4648. Recours à Apache Commons Codec uniquement s'il est déjà dans ton classpath et que tu as besoin de la méthode de validation isBase64() ou du streaming Base64OutputStream. Le BaseEncoding de Guava est une option raisonnable si ton projet dépend déjà de Guava, mais ajouter une dépendance de 3 Mo uniquement pour le Base64 est difficile à justifier.

Trois scénarios, trois choix : service web standard nécessitant Basic Auth ou encodage JWT ? Reste avec le JDK. Projet legacy qui embarque déjà Commons Codec via Spring ou Apache HTTP Client ? Utilise-le — inutile d'avoir deux bibliothèques Base64 dans le classpath. Projet utilisant Guava pour le cache et les collections ? Utilise BaseEncoding pour son API fluente et lisible. N'ajoute jamais une bibliothèque uniquement pour l'encodage Base64 — la version JDK est suffisante depuis 2014.

Si tu as besoin de vérifier rapidement un résultat encodé sans exécuter ton code Java, colle-le dans l' encodeur Base64 pour confirmer que la sortie correspond à ce que ton code produit.

Questions fréquentes

Comment encoder une String en Base64 en Java ?

Convertissez d'abord la chaîne en bytes avec getBytes(StandardCharsets.UTF_8), puis passez le tableau de bytes à Base64.getEncoder().encodeToString(). Spécifiez toujours UTF-8 explicitement — appeler getBytes() sans argument de charset utilise le défaut de la plateforme, qui varie selon les systèmes d'exploitation et les configurations JVM.

Java
import java.util.Base64;
import java.nio.charset.StandardCharsets;

String payload = "grant_type=client_credentials&scope=read:metrics";
String encoded = Base64.getEncoder()
    .encodeToString(payload.getBytes(StandardCharsets.UTF_8));
// Z3JhbnRfdHlwZT1jbGllbnRfY3JlZGVudGlhbHMmc2NvcGU9cmVhZDptZXRyaWNz

Quelle est la différence entre Base64.getEncoder() et Base64.getUrlEncoder() ?

Les deux encodent en Base64, mais getUrlEncoder() utilise l'alphabet URL-safe défini dans la RFC 4648 Section 5. Il remplace + par - et / par _ afin que la sortie puisse apparaître dans des URLs et des noms de fichiers sans percent-encoding. L'encodeur standard utilise + et / qui entrent en conflit avec les paramètres de requête URL et les segments de chemin.

Java
byte[] data = "subject=usr_7b3c&role=admin".getBytes(StandardCharsets.UTF_8);

String standard = Base64.getEncoder().encodeToString(data);
// c3ViamVjdD11c3JfN2IzYyZyb2xlPWFkbWlu

String urlSafe = Base64.getUrlEncoder().encodeToString(data);
// c3ViamVjdD11c3JfN2IzYyZyb2xlPWFkbWlu
// (identique ici, mais avec + → - et / → _ quand ces caractères apparaissent)

java.util.Base64 est-il identique en Java 8 et Java 17 ?

Oui. L'API java.util.Base64 n'a pas changé depuis son introduction en Java 8. La classe, ses classes imbriquées Encoder et Decoder, et toutes les méthodes factory (getEncoder, getUrlEncoder, getMimeEncoder) sont identiques sur Java 8, 11, 17 et 21. Aucune migration ni modification de code n'est nécessaire lors d'une mise à jour de JDK.

Java
// Ce code compile et s'exécute de façon identique de Java 8 à Java 21+
import java.util.Base64;
import java.nio.charset.StandardCharsets;

String encoded = Base64.getEncoder()
    .encodeToString("stable-api".getBytes(StandardCharsets.UTF_8));
System.out.println(encoded);  // c3RhYmxlLWFwaQ==

Comment encoder un fichier en Base64 en Java ?

Lisez le fichier dans un tableau de bytes avec Files.readAllBytes(Path) et passez-le à Base64.getEncoder().encodeToString(). Pour les fichiers volumineux qui ne doivent pas être entièrement chargés en mémoire, utilisez Base64.getEncoder().wrap(OutputStream) pour streamer la sortie encodée.

Java
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;

byte[] fileBytes = Files.readAllBytes(Path.of("config/tls-cert.pem"));
String encoded = Base64.getEncoder().encodeToString(fileBytes);

Pourquoi sun.misc.BASE64Encoder a-t-il été déprécié ?

sun.misc.BASE64Encoder était une classe JDK interne qui n'a jamais fait partie de l'API publique. Elle résidait dans le package sun.misc, qu'Oracle déconseillait explicitement d'utiliser. Java 8 a introduit java.util.Base64 comme remplacement officiel, public et supporté. Depuis Java 9 et le système de modules, accéder aux classes sun.misc produit des avertissements ou des erreurs selon la configuration du JDK.

Java
// Ancienne méthode — à NE PAS utiliser, supprimée dans les JDKs modernes
// import sun.misc.BASE64Encoder;
// String encoded = new BASE64Encoder().encode(data);

// Méthode correcte depuis Java 8
import java.util.Base64;
String encoded = Base64.getEncoder().encodeToString(data);

Comment effectuer un aller-retour Base64 encode/decode en Java ?

Encodez avec Base64.getEncoder().encodeToString(bytes) et décodez avec Base64.getDecoder().decode(encodedString). Reconvertissez le tableau de bytes décodé en String avec new String(bytes, StandardCharsets.UTF_8). L'aller-retour préserve les données d'origine exactement — à condition d'utiliser le même charset pour getBytes() et new String().

Java
import java.util.Base64;
import java.nio.charset.StandardCharsets;

// Encodage
String original = "session_token=eyJhbGciOiJSUzI1NiJ9";
byte[] originalBytes = original.getBytes(StandardCharsets.UTF_8);
String encoded = Base64.getEncoder().encodeToString(originalBytes);

// Décodage
byte[] decodedBytes = Base64.getDecoder().decode(encoded);
String decoded = new String(decodedBytes, StandardCharsets.UTF_8);

System.out.println(original.equals(decoded));  // true

Outils associés

  • Base64 DecoderDécodez des chaînes Base64 en leur texte ou format binaire d'origine — l'opération inverse de l'encodage.
  • URL EncoderEncodez des chaînes en percent-encoding pour une utilisation sûre dans les URLs — différent de l'encodage Base64 URL-safe, mais souvent utilisé conjointement.
  • JWT DecoderInspectez des tokens JWT dont les segments d'en-tête et de payload sont encodés en Base64url JSON — décodez-les sans bibliothèque.
  • JSON FormatterFormatez des payloads JSON avant ou après l'encodage Base64 — utile pour déboguer des intégrations API.
Aussi disponible en :JavaScriptPython
AO
Aisha OseiJava Security & API Engineer

Aisha is a Java engineer specialising in application security, Spring Security, and API design. She has worked on identity and access management systems, OAuth 2.0 integrations, and microservice security at scale. She writes about secure Java coding practices, token validation, cryptographic utilities, and the Spring ecosystem from a security-first perspective.

PN
Pavel NovakRéviseur technique

Pavel is a backend engineer with deep roots in the JVM ecosystem, working primarily with Java and Kotlin. He has extensive experience building data-intensive services and integrating third-party APIs at scale. He writes about modern Java features, the Jackson ecosystem, serialisation patterns, and practical approaches to keeping large codebases maintainable.