Base64 Encoding & Decoding in Java

Since Java 8, the standard library includes java.util.Base64 — no external dependencies needed. It provides three encoder types: Basic, URL-safe, and MIME.

Basic Encode and Decode

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

// Encode
String original = "Hello, world!";
String encoded = Base64.getEncoder()
    .encodeToString(original.getBytes(StandardCharsets.UTF_8));
System.out.println(encoded); // "SGVsbG8sIHdvcmxkIQ=="

// Decode
byte[] decodedBytes = Base64.getDecoder().decode(encoded);
String decoded = new String(decodedBytes, StandardCharsets.UTF_8);
System.out.println(decoded); // "Hello, world!"

Always use StandardCharsets.UTF_8 explicitly when converting between String and byte[]. Never rely on the default platform charset.

Without Padding

// Encode without trailing '=' padding
String encoded = Base64.getEncoder()
    .withoutPadding()
    .encodeToString("Hello".getBytes(StandardCharsets.UTF_8));
System.out.println(encoded); // "SGVsbG8"

// Decoder handles both padded and unpadded input
byte[] decoded = Base64.getDecoder().decode(encoded);

URL-Safe Base64

Use the URL encoder when the Base64 output will appear in URLs, filenames, or JWT tokens:

// URL-safe encoding (replaces + with - and / with _)
String urlSafe = Base64.getUrlEncoder()
    .withoutPadding()
    .encodeToString("Hello, world!".getBytes(StandardCharsets.UTF_8));
System.out.println(urlSafe); // "SGVsbG8sIHdvcmxkIQ"

// URL-safe decoding
byte[] decoded = Base64.getUrlDecoder().decode(urlSafe);

MIME Base64 (for Email)

The MIME encoder splits output into 76-character lines separated by CRLF, as required by email standards:

// MIME encoding with line breaks
byte[] largeData = new byte[200]; // some binary data
String mimeEncoded = Base64.getMimeEncoder().encodeToString(largeData);
// Output has \r\n every 76 chars

// Custom line length (e.g., 64 chars)
String customMime = Base64.getMimeEncoder(64, new byte[]{'\n'})
    .encodeToString(largeData);

// MIME decoding (ignores whitespace/line breaks)
byte[] decoded = Base64.getMimeDecoder().decode(mimeEncoded);

Encoding Files

import java.util.Base64;
import java.nio.file.Files;
import java.nio.file.Paths;

// Encode file to Base64 string
byte[] fileBytes = Files.readAllBytes(Paths.get("image.png"));
String encoded = Base64.getEncoder().encodeToString(fileBytes);

// Decode Base64 back to file
byte[] decoded = Base64.getDecoder().decode(encoded);
Files.write(Paths.get("output.png"), decoded);

Streaming Large Files

For large files, use the wrap stream approach to avoid loading the entire file into memory:

import java.util.Base64;
import java.io.*;

// Encode large file with streaming
try (InputStream in = new FileInputStream("large.bin");
     OutputStream out = new FileOutputStream("large.b64");
     OutputStream encoder = Base64.getEncoder().wrap(out)) {
    byte[] buf = new byte[8192];
    int n;
    while ((n = in.read(buf)) != -1) {
        encoder.write(buf, 0, n);
    }
}

// Decode large file with streaming
try (InputStream in = new FileInputStream("large.b64");
     InputStream decoder = Base64.getDecoder().wrap(in);
     OutputStream out = new FileOutputStream("decoded.bin")) {
    byte[] buf = new byte[8192];
    int n;
    while ((n = decoder.read(buf)) != -1) {
        out.write(buf, 0, n);
    }
}

Encoder Comparison

// Summary of the three encoder types:
Base64.getEncoder()      // Standard: uses + and /, padded with =
Base64.getUrlEncoder()   // URL-safe: uses - and _, padded with =
Base64.getMimeEncoder()  // MIME: standard alphabet, 76-char line breaks

// All three can be combined with .withoutPadding():
Base64.getUrlEncoder().withoutPadding()  // Most common for JWTs

Verify your Java Base64 output online

Copy the encoded string from your Java program and paste it here to decode and verify.

Open base64.dev →