Base64 decoderen in Java β€” getDecoder().decode() Gids

Β·Backend EngineerΒ·Beoordeeld doorAisha OseiΒ·Gepubliceerd

Gebruik de gratis Base64 Decode Online direct in je browser β€” geen installatie nodig.

Base64 Decode Online online uitproberen β†’

Base64 decoderen in Java is iets waar ik elke paar dagen op terugval β€” secrets uit Kubernetes-omgevingsvariabelen halen, binaire payloads uit REST APIs lezen, JWT-tokens inspecteren tijdens een debugsessie. Java's ingebouwde java.util.Base64-klasse (sinds JDK 8) biedt drie decoder-varianten: getDecoder() voor standaard Base64, getUrlDecoder() voor URL-veilige invoer, en getMimeDecoder() voor regelafgebroken data zoals e-mailbijlagen. Voor een snelle eenmalige controle zonder code te schrijven verwerkt ToolDeck's Base64 decoder het direct in je browser. Deze handleiding richt zich op Java 8+ en behandelt alle drie decoders, streaming met wrap(InputStream), JWT-payload extractie, bestand- en API-responsdecodering, Apache Commons Codec als alternatief, en de vier fouten die in productie onleesbare uitvoer veroorzaken.

  • βœ“Base64.getDecoder().decode(s) is de standaardbenadering β€” ingebouwd in java.util.Base64 sinds JDK 8, geen afhankelijkheden nodig.
  • βœ“Gebruik getUrlDecoder() voor JWT-tokens en OAuth-payloads β€” zij gebruiken het alfabet met - en _, niet + en /.
  • βœ“getMimeDecoder() negeert regelafbrekingen en witruimte, waardoor het de juiste keuze is voor e-mailbijlagen en PEM-certificaten.
  • βœ“decoder.wrap(InputStream) decodeert on-the-fly voor grote bestanden zonder alles in geheugen te laden.
  • βœ“De standaard decoder is strikt β€” afsluitende newlines, spaties of tekens van het verkeerde alfabet gooien direct een IllegalArgumentException.

Wat is Base64-decodering?

Base64-codering converteert binaire data naar een 64-tekens ASCII-representatie zodat het veilig door tekstkanalen kan worden verstuurd β€” JSON-velden, HTTP-headers, XML-documenten, e-mailberichten. Decodering keert dit om: elke 4 Base64-tekens worden teruggezet naar 3 originele bytes. De =-padding aan het einde geeft aan hoeveel bytes er zijn toegevoegd om de laatste groep te vullen. Base64 is geen versleuteling β€” iedereen kan het terugdraaien. Het doel is transportveiligheid, niet geheimhouding.

Typische Java-decoderingsscenario's: configuratiewaarden ophalen die als Base64-omgevingsvariabelen zijn geΓ―njecteerd, binaire bestandsinhoud uitpakken uit cloud-API-responses, PEM-gecodeerde certificaten lezen, en JWT-token-payloads inspecteren tijdens het debuggen.

Before Β· text
After Β· text
ZGItcHJvZC51cy1lYXN0LTEuYW1hem9uYXdzLmNvbTo1NDMy
db-prod.us-east-1.amazonaws.com:5432

Base64.getDecoder().decode() β€” De standaard decodeermethode

De java.util.Base64-klasse is toegevoegd in JDK 8 en verving de oude sun.misc.BASE64Decoder waar iedereen op vertrouwde. Geen externe afhankelijkheden nodig β€” gewoon import java.util.Base64 en Base64.getDecoder().decode() aanroepen. De methode accepteert een String of een byte[] en retourneert een byte[] van de gedecodeerde data.

Minimaal werkend voorbeeld

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

public class DecodeCredential {
    public static void main(String[] args) {
        // Kubernetes secret-waarde, Base64-gecodeerd
        String encoded = "ZGItcHJvZC51cy1lYXN0LTEuYW1hem9uYXdzLmNvbTo1NDMy";

        byte[] decodedBytes = Base64.getDecoder().decode(encoded);
        String connectionString = new String(decodedBytes, StandardCharsets.UTF_8);

        System.out.println(connectionString);
        // db-prod.us-east-1.amazonaws.com:5432
    }
}

Geef altijd StandardCharsets.UTF_8 op bij het aanmaken van de String. De constructor zonder argumenten new String(bytes) gebruikt de standaardcodering van het platform, die per systeem verschilt. Op een Windows-server met Cp1252 als standaard worden multi-byte UTF-8-tekens stilzwijgend gecorrumpeerd.

Roundtrip-verificatie

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

public class RoundTrip {
    public static void main(String[] args) {
        String original = "redis://cache-prod.internal:6379/session-store";

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

        byte[] decoded = Base64.getDecoder().decode(encoded);
        String recovered = new String(decoded, StandardCharsets.UTF_8);

        System.out.println(recovered.equals(original)); // true
    }
}

Decoderen naar een vooraf gealloceerde buffer

De overload met drie argumenten decode(byte[] src, byte[] dst) schrijft direct naar een doelbuffer en retourneert het aantal geschreven bytes. Dit vermijdt een extra allocatie op veelgebruikte codepaden:

Java 8+
import java.util.Base64;

public class DecodeToBuffer {
    public static void main(String[] args) {
        byte[] src = "eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0M30=".getBytes();
        byte[] dst = new byte[1024]; // vooraf gealloceerd

        int len = Base64.getDecoder().decode(src, dst);
        String result = new String(dst, 0, len);

        System.out.println(result);
        // {"host":"10.0.1.50","port":8443}
    }
}
Opmerking:decode() gooit een IllegalArgumentException als de invoer tekens bevat buiten het Base64-alfabet (inclusief regelafbrekingen en spaties). Als je invoer mogelijk witruimte bevat, schakel dan over naar getMimeDecoder() of strip het eerst met encoded.strip() vΓ³Γ³r het decoderen.

Base64 decoderen naar niet-standaard types en aangepaste objecten

Ruwe byte[] van decode() moet vaak iets specifieker worden: een UUID, een geserialiseerd Java-object, een protobuf-bericht of een tijdstempel. De decoder retourneert altijd bytes β€” de conversie naar domeintypen is jouw verantwoordelijkheid.

Base64 naar UUID

Java 8+
import java.util.Base64;
import java.nio.ByteBuffer;
import java.util.UUID;

public class DecodeUUID {
    public static UUID fromBase64(String encoded) {
        byte[] bytes = Base64.getUrlDecoder().decode(encoded);
        ByteBuffer bb = ByteBuffer.wrap(bytes);
        return new UUID(bb.getLong(), bb.getLong());
    }

    public static void main(String[] args) {
        // Compacte Base64-gecodeerde UUID uit een API-response
        String encoded = "f47ac10b-58cc-4372-a567-0e02b2c3d479";
        UUID original = UUID.fromString(encoded);

        // Coderen naar Base64 (compacte vorm β€” 22 tekens vs 36)
        ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
        bb.putLong(original.getMostSignificantBits());
        bb.putLong(original.getLeastSignificantBits());
        String compact = Base64.getUrlEncoder().withoutPadding()
            .encodeToString(bb.array());
        System.out.println(compact); // 9HrBC1jMQ3KlZw4CssPUeQ

        // Terug decoderen
        UUID recovered = fromBase64(compact);
        System.out.println(recovered); // f47ac10b-58cc-4372-a567-0e02b2c3d479
    }
}

Base64 naar gedeserialiseerd JSON-object met Jackson

Java 8+
import java.util.Base64;
import java.nio.charset.StandardCharsets;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Instant;

public class DecodeJsonPayload {
    record DeployEvent(String service, String region, Instant deployedAt, int replicas) {}

    public static void main(String[] args) throws Exception {
        // Base64-gecodeerde JSON-payload van een message queue
        String encoded = "eyJzZXJ2aWNlIjoicGF5bWVudC1nYXRld2F5Iiwi"
            + "cmVnaW9uIjoiZXUtd2VzdC0xIiwiZGVwbG95ZWRBdCI6"
            + "IjIwMjYtMDMtMTVUMTQ6MzA6MDBaIiwicmVwbGljYXMiOjR9";

        byte[] jsonBytes = Base64.getDecoder().decode(encoded);
        String json = new String(jsonBytes, StandardCharsets.UTF_8);
        System.out.println(json);
        // {"service":"payment-gateway","region":"eu-west-1",
        //  "deployedAt":"2026-03-15T14:30:00Z","replicas":4}

        ObjectMapper mapper = new ObjectMapper();
        mapper.findAndRegisterModules(); // picks up JavaTimeModule
        DeployEvent event = mapper.readValue(jsonBytes, DeployEvent.class);

        System.out.println(event.service());   // payment-gateway
        System.out.println(event.deployedAt()); // 2026-03-15T14:30:00Z
    }
}
Waarschuwing:Gebruik nooit ObjectInputStream om onbetrouwbare Base64-data te deserialiseren. Java-deserialiseringsaanvallen zijn goed gedocumenteerd β€” als de gecodeerde inhoud van een externe bron komt, parseer het dan als JSON of protobuf in plaats van native Java-serialisatie te gebruiken.

Methoden-referentie Base64.Decoder

Alle methoden behoren tot java.util.Base64 en de inner class Base64.Decoder. De drie factory-methoden op Base64 retourneren verschillende decoder-instanties; de decode()- en wrap()-methoden staan op de Decoder-instantie.

Methode
Retourneert
Invoertype
Beschrijving
getDecoder()
Base64.Decoder
β€”
Standaard decoder (RFC 4648 Β§4, alfabet + en / met =-padding)
getUrlDecoder()
Base64.Decoder
β€”
URL-veilige decoder (RFC 4648 Β§5, alfabet - en _ met =-padding)
getMimeDecoder()
Base64.Decoder
β€”
MIME-decoder β€” negeert regelscheidingstekens en niet-Base64-tekens
decode(String src)
byte[]
String
Decodeert de invoerstring naar een nieuwe byte-array
decode(byte[] src)
byte[]
byte[]
Decodeert de invoer-byte-array naar een nieuwe byte-array
decode(byte[] src, byte[] dst)
int
byte[] + byte[]
Decodeert naar een vooraf gealloceerde dst-buffer, retourneert aantal geschreven bytes
wrap(InputStream is)
InputStream
InputStream
Retourneert een stream die Base64-data on-the-fly decodeert

getMimeDecoder() β€” Regelafgebroken en MIME Base64 decoderen

De standaard decoder weigert alles buiten het Base64-alfabet β€” inclusief de \r\n-regelafbrekingen die MIME-gecodeerde inhoud altijd bevat. E-mailbijlagen, PEM-certificaten en sommige oudere API-responses breken Base64-uitvoer af bij 76 tekens per regel. getMimeDecoder() negeert stilzwijgend regelscheidingstekens en elk teken dat niet in het Base64-alfabet staat, zodat het dit direct verwerkt.

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

public class MimeDecode {
    public static void main(String[] args) {
        // PEM-certificaatinhoud β€” afgebroken bij 76 tekens
        String pemBody = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t\r\n"
            + "TUlJQm96Q0NBVWlnQXdJQkFnSUpBSXBhVDJU\r\n"
            + "aVFvZU1BMEdDU3FHU0liM0RRRU==";

        // getDecoder() zou hier IllegalArgumentException gooien
        byte[] decoded = Base64.getMimeDecoder().decode(pemBody);
        System.out.println(new String(decoded, StandardCharsets.UTF_8));
        // -----BEGIN CERTIFICATE-----
        // MIIBozCCAUigAwIBAgIJAIpaT2T...
    }
}
Opmerking:getMimeDecoder() is tolerant: het slaat ongeldige tekens over in plaats van een uitzondering te gooien. Dit is prima voor bekende MIME-data, maar het kan corruptie in willekeurige invoer stilzwijgend doorslikken. Gebruik getDecoder() als je strikte validatie wilt.

Base64 decoderen vanuit een bestand en API-response

Een Base64-gecodeerd bestand van schijf lezen

Binaire bestanden (afbeeldingen, certificaten, versleutelde blobs) worden soms op schijf opgeslagen als Base64-tekst. Lees het bestand, decodeer het, schrijf de binaire uitvoer:

Java 8+
import java.util.Base64;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class DecodeFile {
    public static void main(String[] args) {
        Path inputPath = Path.of("tls-cert.pem.b64");
        Path outputPath = Path.of("tls-cert.pem");

        try {
            String encoded = Files.readString(inputPath).strip();
            byte[] decoded = Base64.getMimeDecoder().decode(encoded);
            Files.write(outputPath, decoded);

            System.out.printf("Decoded %d bytes β†’ %s%n", decoded.length, outputPath);
        } catch (IOException e) {
            System.err.println("File error: " + e.getMessage());
        } catch (IllegalArgumentException e) {
            System.err.println("Invalid Base64: " + e.getMessage());
        }
    }
}

Een Base64-veld decoderen uit een HTTP API-response

Cloud-APIs (AWS KMS, GitHub Contents, Vault) retourneren binaire data vaak als Base64-strings in JSON. Parseer eerst de JSON en decodeer daarna het doelveld:

Java 11+
import java.util.Base64;
import java.nio.charset.StandardCharsets;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class DecodeApiResponse {
    public static void main(String[] args) {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.example.com/secrets/db-password"))
            .header("Authorization", "Bearer sk-prod-9f8e7d6c")
            .build();

        try {
            HttpResponse<String> response = client.send(
                request, HttpResponse.BodyHandlers.ofString());

            if (response.statusCode() != 200) {
                System.err.printf("Unexpected status: %d%n", response.statusCode());
                return;
            }

            ObjectMapper mapper = new ObjectMapper();
            JsonNode root = mapper.readTree(response.body());

            // API returns: {"name":"db-password","value":"cG9zdGdyZXM6eGs5...","version":3}
            String encodedValue = root.get("value").asText();
            byte[] decoded = Base64.getDecoder().decode(encodedValue);
            String secret = new String(decoded, StandardCharsets.UTF_8);

            System.out.println("Secret: " + secret);
            // Secret: postgres:xk9mP2qR@db-prod:5432/orders
        } catch (Exception e) {
            System.err.println("Failed to fetch secret: " + e.getMessage());
        }
    }
}
Opmerking:Wikkel de decode-aanroep in een eigen try-catch voor IllegalArgumentException, los van de netwerkfouten. Wanneer je I/O-uitzonderingen en decoderingsproblemen mengt, wordt debuggen lastiger β€” je wilt meteen weten of de API slechte data heeft geretourneerd of het netwerk heeft gefaald.

Base64 decoderen via de opdrachtregel

Je hebt niet altijd een Java-programma nodig. Elk Linux- en macOS-systeem heeft een base64-commando, en JDK 9+ wordt geleverd met jshell voor interactieve Java-oneliners. Voor snelle inspectie tijdens het debuggen zijn deze sneller dan een klasse compileren.

bash
# Decode a Base64 string (Linux / macOS)
echo "eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0M30=" | base64 --decode
# {"host":"10.0.1.50","port":8443}

# Decode and pretty-print with jq
echo "eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0M30=" | base64 --decode | jq .
# {
#   "host": "10.0.1.50",
#   "port": 8443
# }

# Quick decode with jshell (JDK 9+)
echo 'System.out.println(new String(java.util.Base64.getDecoder().decode("c2VydmVyLWNvbmZpZw==")))' | jshell -
# server-config

# macOS uses -D instead of --decode
echo "c2VydmVyLWNvbmZpZw==" | base64 -D

Voor het direct plakken van gecodeerde strings in een browser verwerkt ToolDeck's Base64 decoder zowel standaard- als URL-veilige varianten zonder enige configuratie.

Hoogprestatie-alternatief: Apache Commons Codec

Java's ingebouwde java.util.Base64 is al goed geoptimaliseerd β€” JDK 11+ gebruikt intrinsics op x86 voor codering en decodering. Voor de meeste applicaties is er geen reden om een third-party library te gebruiken. Dat gezegd hebbende, Apache Commons Codec blijft populair in legacy-codebases en biedt Base64InputStream voor streaming-decodering met automatische witruimteverwerking.

XML (Maven)
<!-- pom.xml -->
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.17.0</version>
</dependency>
Java 8+
import org.apache.commons.codec.binary.Base64;

public class CommonsCodecDecode {
    public static void main(String[] args) {
        // Commons Codec is toleranter β€” verwerkt witruimte en regelafbrekingen
        String encoded = "eyJob3N0IjoiMTAuMC4xLjUw\nIiwicG9ydCI6ODQ0M30=";
        byte[] decoded = Base64.decodeBase64(encoded);

        System.out.println(new String(decoded));
        // {"host":"10.0.1.50","port":8443}
    }
}

Het voornaamste voordeel van Commons Codec ten opzichte van de ingebouwde API is de standaard tolerantie voor witruimte en de Base64InputStream-klasse die ouder is dan Java's decoder.wrap(). Op Java 8+ dekt de ingebouwde API alles wat Commons Codec doet. Ik grijp alleen naar Commons Codec als het project er al van afhankelijk is.

Grote Base64-bestanden streamen met decoder.wrap()

Een Base64-bestand van 200 MB laden met Files.readString() en dan decode() aanroepen alloceert ongeveer 350 MB heap: de gecodeerde string plus de gedecodeerde byte-array. decoder.wrap(InputStream) decodeert on-the-fly, waardoor het geheugengebruik constant blijft.

Java 8+
import java.util.Base64;
import java.io.*;
import java.nio.file.*;

public class StreamDecode {
    public static void main(String[] args) throws IOException {
        Path src = Path.of("database-dump.sql.b64");
        Path dst = Path.of("database-dump.sql");

        try (InputStream in = Base64.getMimeDecoder().wrap(
                 new BufferedInputStream(Files.newInputStream(src)));
             OutputStream out = new BufferedOutputStream(Files.newOutputStream(dst))) {

            byte[] buffer = new byte[8192];
            int bytesRead;
            long total = 0;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
                total += bytesRead;
            }
            System.out.printf("Decoded %d bytes β†’ %s%n", total, dst);
        }
    }
}

Op Java 9+ kun je de leeslus vervangen door in.transferTo(out) β€” dat doet hetzelfde met minder code. Gebruik getMimeDecoder().wrap() in plaats van getDecoder().wrap() als het bestand mogelijk regelafbrekingen bevat (PEM-bestanden, e-mailexports).

Java 9+
import java.util.Base64;
import java.io.*;
import java.nio.file.*;

public class StreamDecodeSimple {
    public static void main(String[] args) throws IOException {
        try (InputStream in = Base64.getMimeDecoder().wrap(
                 new BufferedInputStream(Files.newInputStream(Path.of("backup.tar.b64"))));
             OutputStream out = Files.newOutputStream(Path.of("backup.tar"))) {
            in.transferTo(out); // Java 9+
        }
    }
}
Waarschuwing:getDecoder().wrap() tolereert geen regelafbrekingen in de stream. Als de Base64-data newlines bevat (afgebroken bij 76 tekens), gebruik dan getMimeDecoder().wrap() β€” anders produceert de stream stilzwijgend gecorrumpeerde uitvoer of gooit een uitzondering op een onverwachte leespositie.

Base64 JWT-payload decoderen in Java zonder een JWT-bibliotheek

Een JWT bestaat uit drie Base64url-gecodeerde segmenten gescheiden door punten. Het middelste segment is de payload β€” het deel dat je tijdens het debuggen wilt inzien. Je kunt het decoderen zonder jjwt of Nimbus te importeren. Splits op ., decodeer het tweede deel met getUrlDecoder(), en parseer de resulterende JSON:

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

public class JWTInspect {
    public static String decodeJwtPayload(String token) {
        String[] parts = token.split("\\.");
        if (parts.length != 3) {
            throw new IllegalArgumentException(
                "Invalid JWT: expected 3 segments, got " + parts.length);
        }
        // JWT uses URL-safe Base64 without padding
        byte[] payload = Base64.getUrlDecoder().decode(parts[1]);
        return new String(payload, StandardCharsets.UTF_8);
    }

    public static void main(String[] args) {
        String token = "eyJhbGciOiJSUzI1NiJ9"
            + ".eyJzdWIiOiJ1c3ItNjcyIiwiaXNzIjoiYXV0aC5leGFtcGxlLmNvbSIs"
            + "ImV4cCI6MTc0MTk1NjgwMCwicm9sZXMiOlsiYWRtaW4iLCJiaWxsaW5nIl19"
            + ".SIGNATURE_PLACEHOLDER";

        String payload = decodeJwtPayload(token);
        System.out.println(payload);
        // {"sub":"usr-672","iss":"auth.example.com",
        //  "exp":1741956800,"roles":["admin","billing"]}
    }
}

Veelgemaakte fouten

Ik ben al deze fouten tegengekomen in code reviews, en de eerste twee zijn verantwoordelijk voor de overgrote meerderheid van Base64-gerelateerde productiebugs in Java-services.

❌ getDecoder() gebruiken voor URL-veilige invoer

Probleem: JWT-tokens en OAuth-toegangstokens gebruiken het URL-veilige alfabet (- en _). Ze doorgeven aan getDecoder() gooit een IllegalArgumentException omdat - niet in het standaard Base64-alfabet staat.

Oplossing: Controleer je databron: tokens van auth-systemen hebben getUrlDecoder() nodig; MIME-bijlagen hebben getMimeDecoder() nodig.

Before Β· Java
After Β· Java
// JWT header β€” URL-safe, no padding
String header = "eyJhbGciOiJSUzI1NiJ9";
byte[] decoded = Base64.getDecoder().decode(header);
// IllegalArgumentException: Illegal base64 character 2d
String header = "eyJhbGciOiJSUzI1NiJ9";
byte[] decoded = Base64.getUrlDecoder().decode(header);
System.out.println(new String(decoded));
// {"alg":"RS256"}
❌ Geen tekenset opgeven bij het aanmaken van een String

Probleem: new String(bytes) gebruikt de standaardtekenset van de JVM, die per omgeving verschilt. Een Linux CI-server (UTF-8) en een Windows-productiehost (Cp1252) produceren voor dezelfde bytes een ander resultaat.

Oplossing: Geef altijd StandardCharsets.UTF_8 als tweede argument mee.

Before Β· Java
After Β· Java
byte[] decoded = Base64.getDecoder().decode(encoded);
String result = new String(decoded);
// platformafhankelijk β€” kan multi-byte tekens corrumperen
byte[] decoded = Base64.getDecoder().decode(encoded);
String result = new String(decoded, StandardCharsets.UTF_8);
// consistent op alle platforms
❌ Een string met afsluitende witruimte decoderen

Probleem: Base64-strings geplakt vanuit terminals of gelezen uit configuratiebestanden hebben vaak afsluitende newlines. De standaard decoder weigert elk teken buiten het Base64-alfabet.

Oplossing: Roep .strip() aan op de invoer vΓ³Γ³r het decoderen, of schakel over naar getMimeDecoder() die witruimte negeert.

Before Β· Java
After Β· Java
// Gelezen uit omgevingsvariabele β€” heeft een afsluitende newline
String encoded = System.getenv("DB_PASSWORD_B64"); // "cG9zdGdyZXM=
"
byte[] decoded = Base64.getDecoder().decode(encoded);
// IllegalArgumentException: Illegal base64 character a
String encoded = System.getenv("DB_PASSWORD_B64");
byte[] decoded = Base64.getDecoder().decode(encoded.strip());
System.out.println(new String(decoded, StandardCharsets.UTF_8));
// postgres
❌ Binaire data naar String converteren

Probleem: new String(decoded) aanroepen op binaire inhoud (afbeeldingen, protobuf, versleutelde blobs) produceert een ongeldige String. Het later terug naar bytes converteren corrumpeert de data stilzwijgend omdat de String-constructor ongeldige UTF-8-reeksen vervangt.

Oplossing: Bewaar binaire data als byte[] door je gehele pipeline. Converteer alleen naar String als je weet dat de inhoud tekst is.

Before Β· Java
After Β· Java
byte[] decoded = Base64.getDecoder().decode(pngBase64);
String imageStr = new String(decoded); // corrumpeert binaire data
Files.writeString(Path.of("image.png"), imageStr); // kapot bestand
byte[] decoded = Base64.getDecoder().decode(pngBase64);
// Bytes direct schrijven β€” geen String-conversie
Files.write(Path.of("image.png"), decoded);

Methodevergelijking

De ingebouwde decoders dekken de meeste use cases. Apache Commons Codec en Guava zijn alternatieven die je in oudere codebases kunt tegenkomen.

Methode
Encoderingsvariant
Negeert witruimte
Streaming
Aangepaste types
Installatie vereist
Base64.getDecoder()
Standaard (+, /)
βœ—
βœ—
βœ—
Nee (JDK 8+)
Base64.getUrlDecoder()
URL-veilig (-, _)
βœ—
βœ—
βœ—
Nee (JDK 8+)
Base64.getMimeDecoder()
MIME (regelafbrekingen OK)
βœ“
βœ—
βœ—
Nee (JDK 8+)
decoder.wrap(InputStream)
Elke variant
Afhankelijk van decoder
βœ“
βœ—
Nee (JDK 8+)
Apache Commons Base64InputStream
Standaard / URL-veilig
βœ“
βœ“
βœ—
Ja (commons-codec)
Apache Commons Base64.decodeBase64()
Standaard
βœ“
βœ—
βœ—
Ja (commons-codec)
Guava BaseEncoding.base64().decode()
Standaard
βœ—
βœ—
βœ—
Ja (guava)

Voor JWT-tokens en moderne API-payloads: getUrlDecoder(). Voor e-mailbijlagen en PEM-certificaten: getMimeDecoder(). Voor grote bestanden waarbij geheugen een rol speelt: decoder.wrap(InputStream). Al het overige: getDecoder(). Apache Commons Codec is alleen zinvol als het al in je dependency-tree zit.

Voor snelle verificatie tijdens de ontwikkeling is de online Base64 decoder sneller dan het schrijven van een wegwerpklasse.

Veelgestelde vragen

Hoe decodeer ik een Base64-string in Java?

Importeer java.util.Base64 en roep Base64.getDecoder().decode(encodedString) aan. Dit retourneert een byte[] β€” wikkel het in new String(bytes, StandardCharsets.UTF_8) om leesbare tekst te krijgen. Voor URL-veilige Base64 (gebruikt in JWTs) vervang je getDecoder() door getUrlDecoder().

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

byte[] decoded = Base64.getDecoder().decode("c2VydmVyLWNvbmZpZw==");
String result = new String(decoded, StandardCharsets.UTF_8);
System.out.println(result); // server-config

Wat is het verschil tussen getDecoder() en getMimeDecoder() in Java?

getDecoder() is strikt β€” hij weigert elk teken buiten het Base64-alfabet, inclusief regelafbrekingen. getMimeDecoder() tolereert regelscheidingstekens (\r\n) en negeert niet-Base64-tekens, waardoor het de juiste keuze is voor het decoderen van e-mailbijlagen en PEM-certificaten waarbij de data per 76 tekens is afgebroken.

Java 8+
String wrapped = "c2VydmVyLWNv\r\nbmZpZw==";

// getDecoder() gooit IllegalArgumentException
// Base64.getDecoder().decode(wrapped); // MISLUKT

// getMimeDecoder() verwerkt dit correct
byte[] decoded = Base64.getMimeDecoder().decode(wrapped);
System.out.println(new String(decoded)); // server-config

Hoe decodeer ik een URL-veilige Base64-string in Java?

Gebruik Base64.getUrlDecoder().decode(encoded). De URL-decoder verwacht het alfabet met - en _ zoals gedefinieerd in RFC 4648 Β§5, in plaats van + en /. JWT-tokens gebruiken altijd dit alfabet. Als de padding (=) is weggelaten (gebruikelijk bij JWTs), verwerkt de URL-decoder dat alsnog β€” Java's URL-decoder accepteert zowel gepadde als ongepadde invoer.

Java 8+
import java.util.Base64;

// JWT-header β€” URL-veilig, zonder padding
String jwtHeader = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
byte[] decoded = Base64.getUrlDecoder().decode(jwtHeader);
System.out.println(new String(decoded));
// {"alg":"HS256","typ":"JWT"}

Hoe decodeer ik een groot Base64-bestand via streaming in Java?

Gebruik decoder.wrap(inputStream) om een FileInputStream in te pakken. De geretourneerde InputStream decodeert Base64 on-the-fly terwijl je bytes leest, zodat het geheugengebruik constant blijft ongeacht de bestandsgrootte. Koppel het aan een BufferedInputStream of gebruik het direct met Files.copy() voor de beste doorvoer.

Java 8+
import java.util.Base64;
import java.io.*;
import java.nio.file.*;

try (InputStream in = Base64.getDecoder().wrap(
        new BufferedInputStream(new FileInputStream("payload.b64")));
     OutputStream out = new FileOutputStream("payload.bin")) {
    in.transferTo(out);
}

Waarom gooit Base64.getDecoder().decode() een IllegalArgumentException?

De standaard decoder is strikt: hij weigert regelafbrekingen, spaties en elk teken buiten A-Za-z0-9+/=. Drie veelvoorkomende oorzaken: de invoer heeft een afsluitende newline (strip hem), de invoer gebruikt URL-veilige tekens zoals - en _ (schakel over naar getUrlDecoder()), of de invoer is afgebroken bij 76 tekens (schakel over naar getMimeDecoder()). Inspecteer altijd de ruwe bytes als de foutmelding onduidelijk is.

Java 8+
String raw = "c2VydmVyLWNvbmZpZw==\n"; // afsluitende newline

// Optie 1: witruimte verwijderen
byte[] decoded = Base64.getDecoder().decode(raw.strip());

// Optie 2: MIME-decoder gebruiken die witruimte negeert
byte[] decoded2 = Base64.getMimeDecoder().decode(raw);

Kan ik Base64 decoderen in Java zonder java.util.Base64?

Ja, maar op Java 8+ is daar geen goede reden voor. VΓ³Γ³r Java 8 gebruikten ontwikkelaars sun.misc.BASE64Decoder (intern, verwijderd in Java 9+), javax.xml.bind.DatatypeConverter.parseBase64Binary() (verwijderd in Java 11), of Apache Commons Codec. Alle drie zijn ofwel verouderd of vereisen een extra afhankelijkheid. Gebruik java.util.Base64 β€” het is sneller, zit standaard in de JDK, en ondersteunt alle drie de varianten (standaard, URL-veilig, MIME).

Gerelateerde tools

  • Base64 Encoder β€” codeer tekst of binaire data naar Base64 in de browser, handig voor het genereren van testfixtures om in je Java-unit tests te plakken.
  • JWT Decoder β€” splits en decodeer alle drie JWT-segmenten tegelijk, met veld-voor-veld payload-inspectie β€” sneller dan een Java-klasse schrijven als je alleen een token wilt inlezen.
  • URL Decoder β€” percent-decodeer URL-gecodeerde strings, nuttig wanneer API-responses Base64url-data combineren met percent-gecodeerde queryparameters.
  • JSON Formatter β€” na het decoderen van een Base64 JWT-payload of API-configuratie, plak de JSON hier om de structuur netjes te formatteren en te valideren.
Ook beschikbaar in:JavaScriptPythonGoC#
PN
Pavel NovakBackend Engineer

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.

AO
Aisha OseiTechnisch beoordelaar

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.