Encode Base64 di Java โ€” Contoh java.util.Base64

ยทJava Security & API EngineerยทDitinjau olehPavel NovakยทDiterbitkan

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

Coba Base64 Encode Online Online โ†’

Setiap kali saya membuat header HTTP Basic Auth, menyematkan sertifikat di Kubernetes secret, atau mengirim data biner melalui JSON API, langkah pertamanya selalu sama: encode Base64 byte mentah menjadi string yang aman untuk ASCII. Java mempermudah ini dengan java.util.Base64, API standar yang tersedia sejak Java 8 yang menggantikan sun.misc.BASE64Encoder yang sudah deprecated. Untuk encoding sekali pakai tanpa menulis kode, Base64 Encoder ToolDeck menanganinya langsung di browser. Panduan ini mencakup Base64.getEncoder(), getUrlEncoder(), getMimeEncoder(), encoding file, streaming dengan wrap(OutputStream), serta kesalahan yang sering dilakukan bahkan oleh developer Java berpengalaman. Semua contoh dapat dikompilasi di Java 8 hingga Java 21+.

  • โœ“Base64.getEncoder().encodeToString(bytes) adalah one-liner standar โ€” sudah ada di JDK sejak Java 8, tidak berubah di Java 17 dan 21.
  • โœ“Selalu teruskan StandardCharsets.UTF_8 ke String.getBytes() sebelum encoding โ€” menghilangkannya menggunakan default platform yang berbeda antar JVM.
  • โœ“getUrlEncoder() menghasilkan output URL-safe (- menggantikan +, _ menggantikan /) dan withoutPadding() menghilangkan karakter = di akhir.
  • โœ“getMimeEncoder() menyisipkan pemisah baris setiap 76 karakter โ€” diperlukan oleh email (MIME) dan format sertifikat PEM.
  • โœ“Untuk file besar, gunakan Base64.getEncoder().wrap(OutputStream) untuk melakukan streaming tanpa memuat seluruh file ke memori.

Apa itu Encoding Base64?

Base64 mengonversi data biner arbitrer menjadi string yang terdiri dari 64 karakter ASCII yang dapat dicetak: A-Z, a-z, 0-9, +, dan /. Setiap 3 byte input menghasilkan tepat 4 karakter Base64. Jika panjang input bukan kelipatan 3, satu atau dua karakter padding = ditambahkan di akhir. Output yang di-encode selalu kira-kira 33% lebih besar dari data aslinya.

Base64 bukan enkripsi. Siapa pun yang memiliki string hasil encoding dapat men-decode-nya. Tujuannya adalah keamanan transport: header HTTP, payload JSON, dokumen XML, dan isi email adalah protokol berbasis teks yang tidak dapat membawa byte biner mentah tanpa korupsi data. Kasus penggunaan Java yang umum mencakup HTTP Basic Authentication, penyematan sertifikat PEM, penyimpanan data biner di kolom teks database, dan pembuatan segmen token JWT.

Before ยท text
After ยท text
deploy-svc:sk_live_4eC39HqLyjWDarjtT1zdp7dc
ZGVwbG95LXN2Yzpza19saXZlXzRlQzM5SHFMeWpXRGFyanRUMXpkcDdkYw==

Base64.getEncoder().encodeToString() โ€” API Standar

java.util.Base64 diperkenalkan di Java 8 sebagai pengganti resmi untuk sun.misc.BASE64Encoder. Kelas ini menyediakan tiga static factory method โ€” masing-masing mengembalikan instance kelas bertingkat Base64.Encoder โ€” yang mencakup tiga varian Base64 yang didefinisikan dalam RFC 4648. Tidak ada library pihak ketiga yang diperlukan. Tidak ada dependensi Maven. Cukup import dan panggil.

Contoh Minimal โ€” Encode sebuah 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
    }
}

Langkah kunci yang sering dilewatkan developer Java pertama kali: sebuah String harus dikonversi ke byte[] sebelum di-encode. Base64 beroperasi pada byte, bukan karakter. encodeToString() menerima byte[] dan mengembalikan String Base64 secara langsung. Jika Anda membutuhkan hasil encoding sebagai byte, gunakan encode(byte[]) โ€” ini mengembalikan byte[] dari karakter Base64 yang di-encode ASCII, berguna ketika Anda menulis langsung ke OutputStream atau membangun frame protokol biner.

HTTP Basic Auth โ€” Kasus Penggunaan Paling Umum

HTTP Basic Authentication mungkin adalah alasan paling umum developer Java menggunakan encoding Base64. Spesifikasi (RFC 7617) mengharuskan string kredensial username:password di-encode Base64 dan ditempatkan di header Authorization. Saya sudah sering melihat ini dilakukan salah โ€” biasanya karena lupa pemisah titik dua atau meng-encode komponen secara terpisah.

Java โ€” HTTP Basic Auth header
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
    }
}

Round-Trip โ€” Encode dan Decode

Java 8+ โ€” encode and decode round-trip
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";

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

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

        System.out.println(original.equals(decoded));  // true
    }
}
Catatan:API java.util.Base64 identik dari Java 8 hingga Java 17 dan Java 21. Tidak diperlukan migrasi saat mengupgrade JDK. Kode yang sama dikompilasi dan dijalankan di versi mana pun sejak Java 8.

Encoding Data Non-String โ€” byte[], UUID, dan Timestamp

Encoding Base64 di Java selalu dimulai dengan byte[]. String dikonversi melalui getBytes(StandardCharsets.UTF_8), tetapi tipe lain memerlukan langkah konversi terlebih dahulu. UUID, timestamp, dan identifier numerik harus diserialisasi ke representasi string atau byte sebelum dapat di-encode Base64.

UUID โ€” Encode sebagai Representasi String

Java โ€” Base64 encoding a 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 Ringkas โ€” Encode 16 Byte Mentah

Jika Anda menginginkan hasil encoding yang lebih pendek, ekstrak 128 bit UUID sebagai 16 byte mentah, bukan mengonversinya ke bentuk string 36 karakter. Output Base64 berkurang dari 48 karakter menjadi 24.

Java โ€” compact UUID encoding
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 karakter vs 48 untuk pendekatan berbasis string

Timestamp dan Payload Campuran

Java โ€” encoding a JSON-like payload with timestamp
import java.time.Instant;
import java.util.Base64;
import java.nio.charset.StandardCharsets;

// Simulasi payload bergaya 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, tanpa padding)
Peringatan:Jangan panggil toString() pada byte[] dengan harapan mendapatkan isinya โ€” hasilnya adalah identity hash array seperti [B@6d06d69c. Gunakan new String(bytes, StandardCharsets.UTF_8) atau teruskan array byte langsung ke encodeToString().

Referensi Method Base64.Encoder

Kelas java.util.Base64 mengekspos tiga factory method, masing-masing mengembalikan Base64.Encoder yang dikonfigurasi untuk varian tertentu. Instance encoder bersifat thread-safe dan stateless โ€” buat sekali dan gunakan kembali.

Method
Tipe
Deskripsi
getEncoder()
Base64.Encoder
Mengembalikan encoder RFC 4648 standar menggunakan alfabet standar (A-Z, a-z, 0-9, +, /)
getUrlEncoder()
Base64.Encoder
Mengembalikan encoder dengan alfabet URL-safe (- menggantikan +, _ menggantikan /)
getMimeEncoder()
Base64.Encoder
Mengembalikan encoder MIME yang menyisipkan baris baru \r\n setiap 76 karakter
getMimeEncoder(lineLength, lineSeparator)
Base64.Encoder
Encoder MIME dengan panjang baris dan byte pemisah yang dapat dikustomisasi
encoder.withoutPadding()
Base64.Encoder
Mengembalikan encoder yang menghilangkan karakter padding = di akhir
encoder.encode(byte[])
byte[]
Meng-encode array byte, mengembalikan array byte hasil encoding
encoder.encodeToString(byte[])
String
Meng-encode array byte, mengembalikan String hasil encoding secara langsung
encoder.wrap(OutputStream)
OutputStream
Membungkus OutputStream untuk encoding Base64 secara streaming

Base64.getUrlEncoder() โ€” Encoding URL-Safe

Encoder URL-safe menggunakan alfabet alternatif di mana + menjadi - dan / menjadi _, sebagaimana didefinisikan dalam RFC 4648 Section 5. Ini penting ketika string Base64 muncul di parameter query URL, nama file, atau nilai cookie โ€” karakter Base64 standar bertentangan dengan delimiter URL dan karakter yang dicadangkan filesystem.

Java โ€” URL-safe Base64 encoding
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);

// Encoder standar โ€” mengandung + dan / yang merusak URL
String standard = Base64.getEncoder().encodeToString(data);
System.out.println(standard);
// aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s/c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw==

// Encoder URL-safe โ€” aman untuk parameter query dan nama file
String urlSafe = Base64.getUrlEncoder().encodeToString(data);
System.out.println(urlSafe);
// aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s_c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw==

// URL-safe tanpa padding โ€” untuk JWT dan token ringkas
String noPadding = Base64.getUrlEncoder().withoutPadding().encodeToString(data);
System.out.println(noPadding);
// aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s_c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw

Varian withoutPadding() menghilangkan karakter = di akhir. Spesifikasi JWT mengharuskan Base64 URL-safe tanpa padding untuk segmen header dan payload, sehingga getUrlEncoder().withoutPadding() adalah panggilan yang tepat saat membuat atau memanipulasi token JWT secara manual.

Catatan:Method withoutPadding() mengembalikan instance encoder baru โ€” tidak mengubah yang asli. Keduanya dapat ditetapkan ke field static final dan digunakan kembali dengan aman lintas thread.

Encode dari File dan Respons API

Dua skenario dunia nyata yang paling umum untuk encoding Base64 di Java: membaca file biner dari disk (sertifikat, gambar, bundle konfigurasi) dan meng-encode data yang diterima dari respons HTTP.

Encode File ke Base64

Java โ€” encoding a file
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("Asli: %d bytes%n", fileBytes.length);
            System.out.printf("Ter-encode:  %d chars%n", encoded.length());

            // Tulis konten ter-encode ke file teks
            Files.writeString(
                Path.of("certs/server.pem.b64"),
                encoded
            );
        } catch (java.io.IOException e) {
            System.err.println("Gagal membaca file: " + e.getMessage());
        }
    }
}

Encode Body Respons API

Java 11+ โ€” encoding an HTTP response
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("Ter-encode %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("Permintaan gagal: " + e.getMessage());
        }
    }
}

Catatan singkat sebelum bagian CLI: jika Anda hanya perlu menempelkan file atau respons API dan mendapatkan output Base64 tanpa menulis kode, Base64 Encoder online menangani input teks maupun biner.

Encoding Base64 via Command-Line

Terkadang Anda hanya perlu meng-encode string atau file dari terminal โ€” tanpa project Java, tanpa IDE, tanpa langkah build. Sebagian besar sistem Unix dilengkapi perintah base64, dan jika Anda sudah menginstal JDK, Anda bisa menggunakan jshell untuk pendekatan berbasis Java.

Bash โ€” command-line Base64 encoding
# macOS / Linux โ€” encode sebuah string
echo -n "deploy-bot:sk_prod_9f2a7c4e" | base64
# ZGVwbG95LWJvdDpza19wcm9kXzlmMmE3YzRl

# Encode sebuah file
base64 < certs/server.pem > certs/server.pem.b64

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

# Menggunakan java langsung dengan one-liner
java -e 'System.out.println(java.util.Base64.getEncoder().encodeToString(args[0].getBytes()))' "my-secret"
# Catatan: java -e memerlukan JDK 23+ (JEP 477)

Pendekatan jshell sangat berguna saat Anda perlu memverifikasi bahwa kode Java menghasilkan output yang sama dengan tool Unix, atau saat men-debug ketidaksesuaian antara yang dikirim service Anda dan yang diterima penerima. Saya memiliki alias shell untuk itu.

Catatan:Di macOS, perintah base64 menggunakan -D untuk decoding. Di Linux (GNU coreutils) menggunakan -d. Perilaku encoding identik di keduanya. Flag -w 0 di Linux menonaktifkan pembungkusan baris pada output, yang biasanya diinginkan saat melakukan pipe ke perintah lain.

Apache Commons Codec โ€” Alternatif Berperforma Tinggi

Untuk sebagian besar aplikasi, java.util.Base64 sudah cukup cepat. Namun jika Anda memproses jutaan operasi encoding dalam loop ketat โ€” seperti pipeline ingesti log atau message broker dengan throughput tinggi โ€” Apache Commons Codec layak di-benchmark. Library ini sudah ada sejak jauh sebelum Java 8 dan menyediakan alternatif yang telah teruji dengan permukaan API yang sedikit berbeda.

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

// Encoding standar
String encoded = Base64.encodeBase64String(telemetryPayload);

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

// Periksa apakah sebuah string adalah Base64 yang valid
boolean valid = Base64.isBase64(encoded);
System.out.println(valid);  // true

Apache Commons Codec juga menyediakan Base64OutputStream dan Base64InputStream untuk skenario streaming, serta metode validasi yang tidak dimiliki encoder JDK. Jika Commons Codec sudah ada di dependency tree Anda (banyak proyek Apache yang menyertakannya), tidak ada alasan untuk tidak menggunakannya.

Guava BaseEncoding

Library Guava dari Google menyertakan BaseEncoding yang menyediakan API fluent untuk Base64 dengan pemisah baris yang dapat dikonfigurasi, kontrol padding, dan dukungan untuk alfabet standar maupun URL-safe. API-nya terbaca dengan jelas, tetapi menambahkan Guava (sekitar 3 MB) hanya untuk encoding Base64 adalah terlalu berlebihan. Jika Guava sudah ada di proyek Anda untuk koleksi atau utilitas caching-nya, API encoding adalah bonus yang berguna.

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 standar
String standard = BaseEncoding.base64().encode(webhookPayload);

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

// Tanpa padding
String noPad = BaseEncoding.base64Url().omitPadding().encode(webhookPayload);

// Dengan pemisah baris (gaya PEM)
String wrapped = BaseEncoding.base64()
    .withSeparator("\n", 64)
    .encode(webhookPayload);

Base64.getMimeEncoder() โ€” Output MIME dan PEM dengan Pemisah Baris

Encoder MIME menyisipkan pemisah baris \r\n setiap 76 karakter, sesuai dengan spesifikasi MIME (RFC 2045). Sertifikat PEM, lampiran email S/MIME, dan beberapa API lama mengharapkan format ini. Encoder standar dan URL-safe menghasilkan satu baris yang tidak terputus โ€” jika Anda meneruskan outputnya ke sistem yang mengharapkan Base64 dengan pemisah baris, sistem tersebut mungkin gagal secara diam-diam atau menolak data tersebut.

Java โ€” MIME Base64 encoding
import java.util.Base64;
import java.nio.charset.StandardCharsets;

// Simulasi body sertifikat PEM
byte[] certData = new byte[256];  // Dalam praktik, baca dari file .der
new java.security.SecureRandom().nextBytes(certData);

// Encoder MIME default โ€” 76 karakter per baris, pemisah \r\n
String mimeEncoded = Base64.getMimeEncoder().encodeToString(certData);
System.out.println(mimeEncoded);
// QYx2K3p8Xg7JmN1R+wFkLd...  (76 karakter)
// Ht5Bv9CzAq0PnSjYl8WxUe...  (76 karakter)
// ...

// Encoder MIME kustom โ€” 64 karakter per baris (standar PEM), pemisah \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-----");
Peringatan:Jangan gunakan getMimeEncoder() untuk token JWT, header HTTP, atau parameter URL. Pemisah baris akan merusak data dalam konteks tersebut. Gunakan getEncoder() atau getUrlEncoder() sebagai gantinya.

Streaming File Besar dengan Base64.getEncoder().wrap()

Memuat seluruh file ke dalam byte[] dengan Files.readAllBytes() berfungsi untuk file kecil, tetapi untuk file di atas 50-100 MB Anda berisiko mengalami OutOfMemoryError. JDK menyediakan Base64.getEncoder().wrap(OutputStream), yang mengembalikan OutputStream yang meng-encode data secara langsung saat Anda menulisnya. Byte ter-encode mengalir ke stream yang mendasarinya tanpa menyangga seluruh input.

Java โ€” streaming Base64 encoding
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("Streamed %d bytes melalui encoder Base64%n", totalBytes);
        }
        // Menutup base64Out secara otomatis mem-flush byte padding terakhir
    }
}

Blok try-with-resources menangani flushing dan penutupan. Satu detail yang sering mengejutkan orang: padding Base64 terakhir hanya ditulis saat OutputStream yang membungkus ditutup. Jika Anda lupa menutupnya (atau hanya menutup stream terluar), beberapa karakter terakhir dari output ter-encode mungkin hilang.

Streaming ke Network Socket

Method wrap() berfungsi dengan OutputStream apa pun โ€” output file, output socket, body respons HTTP, bahkan ByteArrayOutputStream. Berikut contoh penulisan data ter-encode Base64 langsung ke buffer dalam memori, yang berguna untuk unit testing atau membangun payload yang akan dikirim melalui HTTP:

Java โ€” streaming to 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)) {
    // Tulis data dalam potongan โ€” mensimulasikan pembacaan dari stream
    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=

// Verifikasi round-trip
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
Catatan:Ukuran buffer dalam contoh streaming (8192 byte) bukan sembarangan. Ini cocok dengan ukuran buffer default yang digunakan oleh BufferedInputStream dan merupakan keseimbangan yang baik antara penggunaan memori dan overhead system call. Buffer yang lebih kecil meningkatkan jumlah panggilan baca/tulis; buffer yang lebih besar membuang memori tanpa peningkatan throughput yang berarti.

Instance Encoder Thread-Safe โ€” Simpan dan Gunakan Kembali

Base64.Encoder yang dikembalikan oleh factory method bersifat immutable dan thread-safe. Memanggil Base64.getEncoder() pada setiap operasi encoding membuat objek baru setiap kali. JVM kemungkinan akan mengoptimasi ini, tetapi menyimpan encoder dalam field static final membuat niat lebih jelas dan menghindari alokasi yang tidak perlu di hot path.

Java โ€” reusable encoder instances
import java.util.Base64;
import java.nio.charset.StandardCharsets;

public class TokenService {
    // Buat sekali, gunakan di mana saja โ€” 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);
    }
}

Pola ini sangat berguna di layanan Spring Boot di mana kelas utilitas menangani encoding di beberapa controller atau method service. Panggilan withoutPadding() mengembalikan instance encoder baru, sehingga Anda dapat menyimpan varian dengan padding dan tanpa padding sebagai field terpisah. Setiap panggilan ke encodeToString() atau encode() bersifat stateless โ€” tidak diperlukan sinkronisasi, tidak ada shared mutable state.

Kesalahan Umum

โŒ Memanggil getBytes() tanpa menentukan charset

Masalah: String.getBytes() tanpa argumen charset menggunakan encoding default platform, yaitu windows-1252 di Windows, UTF-8 di sebagian besar sistem Linux, dan bervariasi di macOS. Kode yang sama menghasilkan output Base64 berbeda di mesin yang berbeda.

Solusi: Selalu teruskan StandardCharsets.UTF_8 secara eksplisit.

Before ยท Java
After ยท Java
String text = "ะšะปัŽั‡ ะดะพัั‚ัƒะฟะฐ: prod-east";
byte[] bytes = text.getBytes();  // default platform โ€” tidak dapat diprediksi
String encoded = Base64.getEncoder().encodeToString(bytes);
String text = "ะšะปัŽั‡ ะดะพัั‚ัƒะฟะฐ: prod-east";
byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
String encoded = Base64.getEncoder().encodeToString(bytes);
โŒ Menggunakan encoder standar untuk parameter URL

Masalah: Base64.getEncoder() menghasilkan karakter + dan /. Ketika ditempatkan dalam query string URL, + ditafsirkan sebagai spasi dan / sebagai pemisah path, secara diam-diam merusak nilai di sisi penerima.

Solusi: Gunakan Base64.getUrlEncoder() untuk nilai apa pun yang akan muncul dalam URL.

Before ยท Java
After ยท Java
// Token dalam parameter query URL โ€” akan rusak
String token = Base64.getEncoder()
    .encodeToString(sessionData);
String url = "https://auth.internal/verify?token=" + token;
// Encoding URL-safe โ€” tidak ada karakter + atau /
String token = Base64.getUrlEncoder()
    .withoutPadding()
    .encodeToString(sessionData);
String url = "https://auth.internal/verify?token=" + token;
โŒ Men-decode dengan varian encoder yang salah

Masalah: Meng-encode dengan getUrlEncoder() dan men-decode dengan getDecoder() (atau sebaliknya) melempar IllegalArgumentException karena - dan _ tidak valid dalam alfabet Base64 standar, dan + dan / tidak valid dalam alfabet URL-safe.

Solusi: Selalu decode dengan decoder yang sesuai: getUrlDecoder() untuk URL-safe, getDecoder() untuk standar.

Before ยท Java
After ยท Java
String encoded = Base64.getUrlEncoder()
    .encodeToString(data);
// Nanti...
byte[] decoded = Base64.getDecoder()  // decoder SALAH
    .decode(encoded);
// IllegalArgumentException jika encoded mengandung - atau _
String encoded = Base64.getUrlEncoder()
    .encodeToString(data);
// Nanti...
byte[] decoded = Base64.getUrlDecoder()  // decoder yang sesuai
    .decode(encoded);
โŒ Tidak menutup OutputStream wrap()

Masalah: Encoder streaming men-buffer hingga 2 byte input sambil menunggu grup 3 byte lengkap. Jika Anda tidak menutup OutputStream yang membungkus, 1-4 karakter Base64 terakhir (termasuk padding) tidak pernah ditulis.

Solusi: Gunakan try-with-resources, atau panggil close() secara eksplisit pada stream yang dibungkus sebelum membaca output.

Before ยท Java
After ยท Java
ByteArrayOutputStream baos = new ByteArrayOutputStream();
 OutputStream b64os = Base64.getEncoder().wrap(baos);
b64os.write(data);
// baos.toString() TIDAK LENGKAP โ€” kehilangan byte terakhir
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (OutputStream b64os = Base64.getEncoder().wrap(baos)) {
    b64os.write(data);
}  // close() mem-flush padding terakhir
String encoded = baos.toString();  // lengkap

Metode Encoding Base64 โ€” Perbandingan

Method
URL-Safe
Streaming
Pemisah Baris
Tipe Kustom
Perlu Install
Base64.getEncoder()
โœ—
โœ“ (wrap)
โœ—
โœ—
Tidak (JDK 8+)
Base64.getUrlEncoder()
โœ“
โœ“ (wrap)
โœ—
โœ—
Tidak (JDK 8+)
Base64.getMimeEncoder()
โœ—
โœ“ (wrap)
โœ“ (76 char)
โœ—
Tidak (JDK 8+)
Apache Commons Codec
โœ“
โœ“
โœ“
โœ—
Dependensi Maven
Guava BaseEncoding
โœ“
โœ“
โœ“ (dapat dikonfigurasi)
โœ—
Dependensi Maven
jcmd / CLI base64
โœ—
โœ“ (pipe)
โœ“
N/A
Install sistem

Untuk sebagian besar proyek: java.util.Base64 adalah pilihan yang tepat. Nol dependensi, sudah ada di JDK, thread-safe, dan mencakup semua tiga varian RFC 4648. Gunakan Apache Commons Codec hanya jika sudah ada di classpath Anda dan Anda membutuhkan metode validasi isBase64() atau streaming Base64OutputStream.BaseEncoding dari Guava adalah pilihan yang wajar jika proyek Anda sudah bergantung pada Guava, tetapi menambahkan dependensi 3 MB hanya untuk Base64 sulit untuk dibenarkan.

Tiga skenario, tiga pilihan: web service standar yang membutuhkan encoding Basic Auth atau JWT? Gunakan JDK. Proyek legacy yang sudah menarik Commons Codec melalui Spring atau Apache HTTP Client? Gunakan saja โ€” tidak ada alasan untuk memiliki dua library Base64 di classpath. Proyek yang menggunakan Guava untuk caching dan koleksi? Gunakan BaseEncoding untuk API fluent-nya yang bersih. Jangan pernah menambahkan library hanya untuk encoding Base64 โ€” versi JDK sudah cukup baik sejak 2014.

Jika Anda perlu memverifikasi hasil encoding dengan cepat tanpa menjalankan kode Java, tempelkan ke Base64 Encoder untuk mengonfirmasi output sesuai dengan yang dihasilkan kode Anda.

Pertanyaan yang Sering Diajukan

Bagaimana cara meng-encode String ke Base64 di Java?

Konversi string ke byte terlebih dahulu menggunakan getBytes(StandardCharsets.UTF_8), lalu teruskan array byte tersebut ke Base64.getEncoder().encodeToString(). Selalu tentukan UTF-8 secara eksplisit โ€” memanggil getBytes() tanpa argumen charset menggunakan default platform, yang berbeda-beda antara sistem operasi dan konfigurasi 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

Apa perbedaan antara Base64.getEncoder() dan Base64.getUrlEncoder()?

Keduanya meng-encode ke Base64, tetapi getUrlEncoder() menggunakan alfabet URL-safe yang didefinisikan dalam RFC 4648 Section 5. Alfabet ini menggantikan + dengan - dan / dengan _ sehingga output dapat muncul di URL dan nama file tanpa perlu percent-encoding. Encoder standar menggunakan + dan / yang bertentangan dengan parameter query URL dan segmen path.

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
// (sama di sini, tetapi + โ†’ - dan / โ†’ _ ketika karakter tersebut muncul)

Apakah java.util.Base64 sama di Java 8 dan Java 17?

Ya. API java.util.Base64 tidak berubah sejak diperkenalkan di Java 8. Kelas ini, kelas Encoder dan Decoder bertingkatnya, serta semua factory method (getEncoder, getUrlEncoder, getMimeEncoder) identik di Java 8, 11, 17, dan 21. Tidak diperlukan migrasi atau perubahan kode saat mengupgrade versi JDK.

Java
// Kode ini dikompilasi dan dijalankan identik di Java 8 hingga 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==

Bagaimana cara meng-encode file ke Base64 di Java?

Baca file ke dalam array byte dengan Files.readAllBytes(Path) dan teruskan ke Base64.getEncoder().encodeToString(). Untuk file besar yang tidak boleh dimuat seluruhnya ke memori, gunakan Base64.getEncoder().wrap(OutputStream) untuk melakukan streaming output yang sudah di-encode.

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

Mengapa sun.misc.BASE64Encoder sudah deprecated?

sun.misc.BASE64Encoder adalah kelas JDK internal yang tidak pernah menjadi bagian dari API publik. Kelas ini berada di paket sun.misc, yang secara eksplisit dilarang penggunaannya oleh Oracle. Java 8 memperkenalkan java.util.Base64 sebagai pengganti resmi, publik, dan didukung. Sejak Java 9 dan sistem modul, mengakses kelas sun.misc menghasilkan peringatan atau error tergantung pada konfigurasi JDK.

Java
// Cara lama โ€” JANGAN digunakan, dihapus di JDK modern
// import sun.misc.BASE64Encoder;
// String encoded = new BASE64Encoder().encode(data);

// Cara yang benar sejak Java 8
import java.util.Base64;
String encoded = Base64.getEncoder().encodeToString(data);

Bagaimana cara melakukan round-trip encode dan decode Base64 di Java?

Encode dengan Base64.getEncoder().encodeToString(bytes) dan decode dengan Base64.getDecoder().decode(encodedString). Konversi array byte hasil decode kembali ke String menggunakan new String(bytes, StandardCharsets.UTF_8). Round-trip mempertahankan data asli dengan tepat โ€” selama Anda menggunakan charset yang sama untuk getBytes() dan new String().

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

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

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

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

Alat Terkait

  • Base64 Decoder โ€” Decode string Base64 kembali ke teks atau bentuk biner aslinya โ€” operasi kebalikan dari encoding.
  • URL Encoder โ€” Percent-encode string untuk penggunaan aman di URL โ€” berbeda dari encoding URL-safe Base64, tetapi sering digunakan bersama.
  • JWT Decoder โ€” Periksa token JWT yang segmen header dan payload-nya dikodekan dengan Base64url JSON โ€” decode tanpa library.
  • JSON Formatter โ€” Pretty-print payload JSON sebelum atau sesudah encoding Base64 โ€” berguna saat men-debug integrasi API.
Tersedia juga dalam: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 NovakPeninjau teknis

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.