Base64 Decode Java โ€” Panduan getDecoder().decode()

ยทBackend EngineerยทDitinjau olehAisha OseiยทDiterbitkan

Gunakan Base64 Decode Online gratis langsung di browser Anda โ€” tidak perlu instalasi.

Coba Base64 Decode Online Online โ†’

Dekode Base64 di Java adalah sesuatu yang sering saya butuhkan setiap beberapa hari โ€” mengambil secrets dari environment variable Kubernetes, membaca payload binary dari REST API, memeriksa token JWT saat sesi debugging. Kelas bawaan Java java.util.Base64 (sejak JDK 8) menyediakan tiga jenis decoder: getDecoder() untuk Base64 standar, getUrlDecoder() untuk input URL-safe, dan getMimeDecoder() untuk data yang dibungkus per baris seperti lampiran email. Untuk pengecekan cepat tanpa menulis kode, Base64 decoder ToolDeck langsung memproses di browser Anda. Panduan ini menargetkan Java 8+ dan mencakup ketiga decoder, streaming dengan wrap(InputStream), ekstraksi payload JWT, dekode file dan respons API, Apache Commons Codec sebagai alternatif, serta empat kesalahan yang menghasilkan output rusak di production.

  • โœ“Base64.getDecoder().decode(s) adalah pendekatan standar โ€” sudah tersedia di java.util.Base64 sejak JDK 8, tanpa dependensi tambahan.
  • โœ“Gunakan getUrlDecoder() untuk token JWT dan payload OAuth โ€” keduanya menggunakan alfabet - dan _, bukan + dan /.
  • โœ“getMimeDecoder() mengabaikan line break dan whitespace, menjadikannya pilihan tepat untuk lampiran email dan sertifikat PEM.
  • โœ“decoder.wrap(InputStream) mendekode secara langsung untuk file besar tanpa memuat semuanya ke memori.
  • โœ“Decoder dasar bersifat ketat โ€” trailing newline, spasi, atau karakter alfabet yang salah langsung melempar IllegalArgumentException.

Apa itu Dekode Base64?

Encoding Base64 mengonversi data binary menjadi representasi ASCII 64-karakter agar dapat melewati saluran text-only dengan aman โ€” field JSON, header HTTP, dokumen XML, isi email. Decoding membalik proses ini: setiap 4 karakter Base64 dipetakan kembali ke 3 byte asli. Padding = di akhir menandakan berapa byte yang ditambahkan untuk mengisi grup terakhir. Base64 bukan enkripsi โ€” siapapun bisa membaliknya. Tujuannya adalah keamanan transport, bukan kerahasiaan.

Skenario dekode Java yang umum: mengekstrak nilai konfigurasi yang diinjeksikan sebagai environment variable Base64, membuka konten file binary dari respons API cloud, membaca sertifikat berformat PEM, dan memeriksa payload token JWT saat debugging.

Before ยท text
After ยท text
ZGItcHJvZC51cy1lYXN0LTEuYW1hem9uYXdzLmNvbTo1NDMy
db-prod.us-east-1.amazonaws.com:5432

Base64.getDecoder().decode() โ€” Metode Dekode Standar

Kelas java.util.Base64 ditambahkan di JDK 8 dan menggantikan sun.misc.BASE64Decoder lama yang dulu banyak digunakan. Tidak perlu dependensi eksternal โ€” cukup import java.util.Base64 dan panggil Base64.getDecoder().decode(). Metode ini menerima String atau byte[] dan mengembalikan byte[] berisi data yang sudah didekode.

Contoh kerja minimal

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

public class DecodeCredential {
    public static void main(String[] args) {
        // Nilai secret Kubernetes, diencoding dengan Base64
        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
    }
}

Selalu tentukan StandardCharsets.UTF_8 saat membuat String. Konstruktor new String(bytes) tanpa argumen menggunakan encoding default platform, yang berbeda antar sistem. Pada server Windows dengan Cp1252 sebagai default, karakter UTF-8 multi-byte akan rusak secara diam-diam.

Verifikasi round-trip

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
    }
}

Dekode ke buffer yang sudah dialokasikan

Overload tiga argumen decode(byte[] src, byte[] dst) menulis langsung ke buffer tujuan dan mengembalikan jumlah byte yang ditulis. Ini menghindari alokasi tambahan pada jalur yang sering dieksekusi:

Java 8+
import java.util.Base64;

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

        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}
    }
}
Catatan:decode() melempar IllegalArgumentException jika input mengandung karakter di luar alfabet Base64 (termasuk line break dan spasi). Jika input Anda mungkin mengandung whitespace, ganti ke getMimeDecoder() atau bersihkan dengan encoded.strip() sebelum mendekode.

Mendekode Base64 dengan Tipe Non-Standar dan Objek Kustom

byte[] mentah dari decode() sering perlu dikonversi menjadi sesuatu yang lebih spesifik: UUID, objek Java yang diserialisasi, pesan protobuf, atau timestamp. Decoder selalu mengembalikan byte โ€” konversi ke tipe domain adalah tanggung jawab Anda.

Base64 ke 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) {
        // UUID dalam format Base64 kompak dari respons API
        String encoded = "f47ac10b-58cc-4372-a567-0e02b2c3d479";
        UUID original = UUID.fromString(encoded);

        // Encode ke Base64 (bentuk kompak โ€” 22 karakter 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

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

Base64 ke objek JSON yang dideserialisasi dengan 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 {
        // Payload JSON berformat Base64 dari 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
    }
}
Peringatan:Jangan pernah menggunakan ObjectInputStream untuk mendeserialisasi data Base64 yang tidak terpercaya. Serangan deserialisasi Java sudah terdokumentasi dengan baik โ€” jika konten yang diencoding berasal dari sumber eksternal, parse sebagai JSON atau protobuf, bukan menggunakan serialisasi Java native.

Referensi Method Base64.Decoder

Semua method berada di java.util.Base64 dan inner class-nya Base64.Decoder. Tiga factory method pada Base64 mengembalikan instance decoder yang berbeda; method decode() dan wrap() berada pada instance Decoder.

Metode
Kembalian
Tipe Input
Deskripsi
getDecoder()
Base64.Decoder
โ€”
Decoder standar (RFC 4648 ยง4, alfabet + dan / dengan padding =)
getUrlDecoder()
Base64.Decoder
โ€”
Decoder URL-safe (RFC 4648 ยง5, alfabet - dan _ dengan padding =)
getMimeDecoder()
Base64.Decoder
โ€”
Decoder MIME โ€” mengabaikan pemisah baris dan karakter non-Base64
decode(String src)
byte[]
String
Mendekode string input ke byte array baru
decode(byte[] src)
byte[]
byte[]
Mendekode byte array input ke byte array baru
decode(byte[] src, byte[] dst)
int
byte[] + byte[]
Mendekode ke buffer dst yang sudah dialokasikan, mengembalikan jumlah byte yang ditulis
wrap(InputStream is)
InputStream
InputStream
Mengembalikan stream yang mendekode data Base64 secara langsung saat dibaca

getMimeDecoder() โ€” Mendekode Base64 MIME dan Berlapis Baris

Decoder dasar menolak apapun di luar alfabet Base64 โ€” termasuk line break \r\n yang selalu ada pada konten berformat MIME. Lampiran email, sertifikat PEM, dan beberapa respons API lama membungkus output Base64 per 76 karakter per baris. getMimeDecoder() secara diam-diam mengabaikan pemisah baris dan karakter yang bukan alfabet Base64, sehingga langsung dapat menangani ini.

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

public class MimeDecode {
    public static void main(String[] args) {
        // Isi sertifikat PEM โ€” dibungkus per 76 karakter
        String pemBody = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t\r\n"
            + "TUlJQm96Q0NBVWlnQXdJQkFnSUpBSXBhVDJU\r\n"
            + "aVFvZU1BMEdDU3FHU0liM0RRRUE==";

        // getDecoder() akan melempar IllegalArgumentException di sini
        byte[] decoded = Base64.getMimeDecoder().decode(pemBody);
        System.out.println(new String(decoded, StandardCharsets.UTF_8));
        // -----BEGIN CERTIFICATE-----
        // MIIBozCCAUigAwIBAgIJAIpaT2T...
    }
}
Catatan:getMimeDecoder() bersifat permisif: ia melewati karakter yang tidak valid daripada melempar exception. Ini baik untuk data MIME yang sudah diketahui, tetapi dapat secara diam-diam menelan kerusakan pada input sembarang. Gunakan getDecoder() jika Anda menginginkan validasi yang ketat.

Dekode Base64 dari File dan Respons API

Membaca file berformat Base64 dari disk

File binary (gambar, sertifikat, blob terenkripsi) kadang disimpan di disk sebagai teks Base64. Baca file, dekode, tulis output binary-nya:

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());
        }
    }
}

Mendekode field Base64 dari respons HTTP API

API cloud (AWS KMS, GitHub Contents, Vault) sering mengembalikan data binary sebagai string Base64 di dalam JSON. Parse JSON-nya terlebih dahulu, lalu dekode field yang dituju:

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 mengembalikan: {"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());
        }
    }
}
Catatan:Bungkus panggilan decode dalam try-catch tersendiri untuk IllegalArgumentException secara terpisah dari error jaringan. Mencampur exception I/O dengan kegagalan dekode mempersulit debugging โ€” Anda ingin tahu segera apakah API mengembalikan data buruk atau jaringan yang gagal.

Dekode Base64 dari Command Line

Anda tidak selalu memerlukan program Java. Setiap sistem Linux dan macOS memiliki perintah base64, dan JDK 9+ dilengkapi jshell untuk one-liner Java interaktif. Untuk inspeksi cepat saat debugging, cara ini lebih cepat daripada mengompilasi sebuah class.

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

# Dekode dan pretty-print dengan jq
echo "eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0M30=" | base64 --decode | jq .
# {
#   "host": "10.0.1.50",
#   "port": 8443
# }

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

# macOS menggunakan -D bukan --decode
echo "c2VydmVyLWNvbmZpZw==" | base64 -D

Untuk menempel string yang sudah diencoding langsung ke browser, Base64 decoder ToolDeck menangani varian standar maupun URL-safe tanpa perlu setup apapun.

Alternatif Berperforma Tinggi: Apache Commons Codec

java.util.Base64 bawaan Java sudah dioptimalkan dengan baik โ€” JDK 11+ menggunakan intrinsic pada x86 untuk encoding dan decoding. Untuk sebagian besar aplikasi, tidak ada alasan untuk menggunakan library pihak ketiga. Namun, Apache Commons Codec tetap populer di codebase lama dan menawarkan Base64InputStream untuk streaming decoding dengan penanganan whitespace otomatis.

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 lebih permisif โ€” menangani whitespace dan line break
        String encoded = "eyJob3N0IjoiMTAuMC4xLjUw\nIiwicG9ydCI6ODQ0M30=";
        byte[] decoded = Base64.decodeBase64(encoded);

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

Keunggulan utama Commons Codec dibanding API bawaan adalah kelonggaran terhadap whitespace secara default dan kelas Base64InputStream-nya yang hadir sebelum decoder.wrap() milik Java. Jika Anda menggunakan Java 8+, API bawaan sudah mencakup semua yang dilakukan Commons Codec. Saya hanya menggunakan Commons Codec ketika project sudah bergantung padanya.

Streaming File Base64 Besar dengan decoder.wrap()

Memuat file Base64 200 MB dengan Files.readString() lalu memanggil decode() mengalokasikan sekitar 350 MB heap: string yang diencoding ditambah byte array yang sudah didekode. decoder.wrap(InputStream) mendekode secara langsung, menjaga penggunaan memori tetap flat.

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);
        }
    }
}

Pada Java 9+ Anda dapat mengganti loop baca dengan in.transferTo(out) โ€” cara yang sama dengan kode lebih sedikit. Gunakan getMimeDecoder().wrap() daripada getDecoder().wrap() jika file mungkin mengandung line break (file PEM, ekspor email).

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+
        }
    }
}
Peringatan:getDecoder().wrap() tidak mentoleransi line break dalam stream. Jika data Base64 memiliki newline (dibungkus per 76 karakter), gunakan getMimeDecoder().wrap() โ€” jika tidak, stream akan menghasilkan output yang rusak secara diam-diam atau melempar exception pada posisi baca yang tidak terduga.

Dekode Payload JWT Base64 di Java Tanpa Library JWT

JWT adalah tiga segmen berformat Base64url yang dipisahkan oleh titik. Segmen tengah adalah payload โ€” bagian yang penting saat debugging. Anda bisa mendekodenya tanpa mengimpor jjwt atau Nimbus. Pecah dengan ., dekode bagian kedua dengan getUrlDecoder(), dan parse JSON yang dihasilkan:

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 menggunakan Base64 URL-safe tanpa 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"]}
    }
}

Kesalahan Umum

Saya pernah menemui setiap kesalahan ini dalam code review, dan dua yang pertama menyumbang sebagian besar bug terkait Base64 di layanan Java production.

โŒ Menggunakan getDecoder() pada input URL-safe

Masalah: Token JWT dan access token OAuth menggunakan alfabet URL-safe (- dan _). Meneruskannya ke getDecoder() melempar IllegalArgumentException karena - tidak ada dalam alfabet Base64 standar.

Solusi: Periksa sumber data Anda: token dari sistem auth memerlukan getUrlDecoder(); lampiran MIME memerlukan getMimeDecoder().

Before ยท Java
After ยท Java
// JWT header โ€” URL-safe, tanpa 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"}
โŒ Tidak menentukan charset saat membuat String

Masalah: new String(bytes) menggunakan charset default JVM, yang berbeda antar environment. Server CI Linux (UTF-8) dan host production Windows (Cp1252) menghasilkan output berbeda untuk byte yang sama.

Solusi: Selalu sertakan StandardCharsets.UTF_8 sebagai argumen kedua.

Before ยท Java
After ยท Java
byte[] decoded = Base64.getDecoder().decode(encoded);
String result = new String(decoded);
// bergantung platform โ€” dapat merusak karakter multi-byte
byte[] decoded = Base64.getDecoder().decode(encoded);
String result = new String(decoded, StandardCharsets.UTF_8);
// konsisten di semua platform
โŒ Mendekode string dengan trailing whitespace

Masalah: String Base64 yang ditempel dari terminal atau dibaca dari file konfigurasi sering memiliki newline di akhir. Decoder dasar menolak karakter apapun di luar alfabet Base64.

Solusi: Panggil .strip() pada input sebelum mendekode, atau ganti ke getMimeDecoder() yang mengabaikan whitespace.

Before ยท Java
After ยท Java
// Dibaca dari environment variable โ€” memiliki trailing 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
โŒ Mengonversi data binary ke String

Masalah: Memanggil new String(decoded) pada konten binary (gambar, protobuf, blob terenkripsi) menghasilkan String yang tidak valid. Mengonversinya kembali ke byte nantinya dapat merusak data secara diam-diam karena konstruktor String mengganti urutan UTF-8 yang tidak valid.

Solusi: Pertahankan data binary sebagai byte[] di seluruh pipeline Anda. Konversi ke String hanya jika Anda tahu kontennya adalah teks.

Before ยท Java
After ยท Java
byte[] decoded = Base64.getDecoder().decode(pngBase64);
String imageStr = new String(decoded); // merusak binary
Files.writeString(Path.of("image.png"), imageStr); // file rusak
byte[] decoded = Base64.getDecoder().decode(pngBase64);
// Tulis byte langsung โ€” tanpa konversi String
Files.write(Path.of("image.png"), decoded);

Perbandingan Method

Decoder bawaan mencakup sebagian besar kasus penggunaan. Apache Commons Codec dan Guava adalah alternatif yang mungkin Anda temukan di codebase lama.

Metode
Varian Encoding
Abaikan Whitespace
Streaming
Tipe Kustom
Perlu Instalasi
Base64.getDecoder()
Standard (+, /)
โœ—
โœ—
โœ—
Tidak (JDK 8+)
Base64.getUrlDecoder()
URL-safe (-, _)
โœ—
โœ—
โœ—
Tidak (JDK 8+)
Base64.getMimeDecoder()
MIME (line breaks OK)
โœ“
โœ—
โœ—
Tidak (JDK 8+)
decoder.wrap(InputStream)
Varian apapun
Tergantung decoder
โœ“
โœ—
Tidak (JDK 8+)
Apache Commons Base64InputStream
Standard / URL-safe
โœ“
โœ“
โœ—
Ya (commons-codec)
Apache Commons Base64.decodeBase64()
Standard
โœ“
โœ—
โœ—
Ya (commons-codec)
Guava BaseEncoding.base64().decode()
Standard
โœ—
โœ—
โœ—
Ya (guava)

Untuk token JWT dan payload API modern: getUrlDecoder(). Untuk lampiran email dan sertifikat PEM: getMimeDecoder(). Untuk file besar di mana memori penting: decoder.wrap(InputStream). Selain itu: getDecoder(). Apache Commons Codec masuk akal hanya jika sudah ada dalam dependency tree Anda.

Untuk verifikasi cepat saat pengembangan, Base64 decoder online lebih cepat daripada menulis class sekali pakai.

Pertanyaan yang Sering Diajukan

Bagaimana cara mendekode string Base64 di Java?

Import java.util.Base64 dan panggil Base64.getDecoder().decode(encodedString). Metode ini mengembalikan byte[] โ€” bungkus dengan new String(bytes, StandardCharsets.UTF_8) untuk mendapatkan teks yang dapat dibaca. Untuk Base64 URL-safe (digunakan pada JWT), ganti getDecoder() dengan 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

Apa perbedaan antara getDecoder() dan getMimeDecoder() di Java?

getDecoder() bersifat ketat โ€” ia menolak karakter apapun di luar alfabet Base64, termasuk line break. getMimeDecoder() mentoleransi pemisah baris (\r\n) dan mengabaikan karakter non-Base64, sehingga menjadi pilihan tepat untuk mendekode lampiran email dan sertifikat PEM yang datanya dibungkus per 76 karakter.

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

// getDecoder() melempar IllegalArgumentException
// Base64.getDecoder().decode(wrapped); // GAGAL

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

Bagaimana cara mendekode string Base64 URL-safe di Java?

Gunakan Base64.getUrlDecoder().decode(encoded). Decoder URL mengharapkan alfabet - dan _ yang didefinisikan dalam RFC 4648 ยง5, bukan + dan /. Token JWT selalu menggunakan alfabet ini. Jika karakter padding (=) dihapus (umum pada JWT), decoder URL tetap dapat menanganinya โ€” decoder URL Java menerima input dengan maupun tanpa padding.

Java 8+
import java.util.Base64;

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

Bagaimana cara mendekode file Base64 besar secara streaming di Java?

Gunakan decoder.wrap(inputStream) untuk membungkus FileInputStream. InputStream yang dikembalikan mendekode Base64 secara langsung saat Anda membaca byte, sehingga penggunaan memori tetap konstan terlepas dari ukuran file. Sambungkan melalui BufferedInputStream atau langsung ke Files.copy() untuk throughput terbaik.

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);
}

Mengapa Base64.getDecoder().decode() melempar IllegalArgumentException?

Decoder dasar bersifat ketat: ia menolak line break, spasi, dan karakter apapun di luar A-Za-z0-9+/=. Tiga penyebab umum: input memiliki newline di akhir (trim terlebih dahulu), input menggunakan karakter URL-safe seperti - dan _ (ganti ke getUrlDecoder()), atau input dibungkus per 76 karakter (ganti ke getMimeDecoder()). Selalu periksa byte mentah jika pesan error tidak jelas.

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

// Opsi 1: trim whitespace
byte[] decoded = Base64.getDecoder().decode(raw.strip());

// Opsi 2: gunakan MIME decoder yang mengabaikan whitespace
byte[] decoded2 = Base64.getMimeDecoder().decode(raw);

Bisakah saya mendekode Base64 di Java tanpa java.util.Base64?

Bisa, tetapi tidak ada alasan yang baik untuk melakukannya di Java 8+. Sebelum Java 8, developer menggunakan sun.misc.BASE64Decoder (internal, dihapus di Java 9+), javax.xml.bind.DatatypeConverter.parseBase64Binary() (dihapus di Java 11), atau Apache Commons Codec. Ketiganya sudah deprecated atau memerlukan dependensi tambahan. Gunakan java.util.Base64 โ€” lebih cepat, sudah tersedia di JDK, dan mencakup semua tiga varian (basic, URL-safe, MIME).

Tools Terkait

  • Base64 Encoder โ€” encode teks atau data binary ke Base64 di browser, berguna untuk membuat test fixture yang bisa langsung ditempel ke unit test Java Anda.
  • JWT Decoder โ€” pisahkan dan dekode ketiga segmen JWT sekaligus, dengan inspeksi payload per field โ€” lebih cepat daripada menulis class Java saat Anda hanya perlu membaca token.
  • URL Decoder โ€” dekode string yang di-percent-encode, berguna saat respons API menggabungkan data Base64url dengan query parameter yang dienkode persen.
  • JSON Formatter โ€” setelah mendekode payload JWT Base64 atau konfigurasi API, tempelkan JSON di sini untuk pretty-print dan validasi strukturnya.
Tersedia juga dalam: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 OseiPeninjau teknis

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.