Langsung ke konten
LeedyBox
Dukung

Penjelasan Base64, Encoding URL, dan JWT

Ketiganya muncul di mana pun data harus dikirim sebagai teks: di URL, header HTTP, JSON, dan token login. Tidak satu pun menyembunyikan apa pun. Panduan ini menjelaskan cara kerja masing-masing, di mana Anda menjumpainya, dan kesalahan yang menjadi penyebab sebagian besar masalah.

Encoding Bukan Enkripsi

Encoding mengubah cara data ditulis agar bisa melewati saluran yang hanya menerima karakter tertentu. Siapa pun dapat membaliknya, karena tidak ada kunci yang terlibat. Enkripsi juga mengubah data, tetapi hanya pemegang kunci yang bisa mengembalikannya. Hash berbeda lagi: sidik jari satu arah yang sama sekali tidak bisa dibalik, seperti dijelaskan dalam Penjelasan Fungsi Hash.

Base64 dan encoding URL adalah encoding. JWT biasanya ditandatangani, yang membuktikan siapa penerbitnya dan bahwa isinya tidak diubah, tetapi isinya hanya di-encode. Jika sebuah nilai harus tetap rahasia, ia memerlukan enkripsi, bukan salah satu format ini.

Cara Kerja Base64

Base64 membaca data tiga byte (24 bit) sekaligus dan membaginya menjadi empat kelompok enam bit. Setiap kelompok adalah angka 0 sampai 63 dan ditulis sebagai satu karakter dari alfabet 64 karakter: A–Z untuk 0–25, a–z untuk 26–51, 0–9 untuk 52–61, lalu + dan /. Kata “Man” menunjukkan langkah-langkahnya:

LangkahMan
Nilai byte7797110
Bit010011010110000101101110
Empat kelompok 6 bit010011 · 010110 · 000101 · 101110 = 19 · 22 · 5 · 46
Base64T W F u → TWFu

Jika panjang masukan bukan kelipatan tiga, kelompok terakhir dilengkapi dan ditandai dengan padding: satu byte sisa menghasilkan dua karakter dan ==, dua byte sisa menghasilkan tiga karakter dan =. “Ma” menjadi TWE= dan “M” menjadi TQ==.

Karena setiap tiga byte menjadi empat karakter, Base64 membuat data sekitar sepertiga lebih besar, ditambah jeda baris yang disisipkan sebagian format. Foto 3 MB yang dikirim sebagai lampiran email berpindah sebagai sekitar 4 MB teks, dan gambar yang disematkan ke stylesheet sebagai data URL sekitar sepertiga lebih berat daripada filenya.

Di Mana Anda Menjumpai Base64

  • Lampiran email (MIME) adalah teks Base64 yang dipotong 76 karakter per baris.
  • Data URL seperti data:image/png;base64,iVBORw0… memasukkan file kecil langsung ke HTML atau CSS.
  • Autentikasi HTTP Basic mengirim user:password sebagai Base64 di header Authorization. Itu hanya menyembunyikan kata sandi dari pandangan sekilas, jadi hanya aman lewat HTTPS.
  • Sertifikat dan kunci dalam file PEM adalah Base64 di antara baris -----BEGIN …----- dan -----END …-----, dipotong 64 karakter.
  • JSON dan XML membawa nilai biner, seperti tanda tangan atau gambar mini, sebagai string Base64 karena keduanya tidak punya tipe biner.

Base64URL dan Padding

Tanda + dan / pada Base64 standar punya arti di URL dan path file, jadi alfabet kedua, Base64URL, memakai - dan _ sebagai gantinya. Biasanya ia juga menghilangkan padding =, karena decoder bisa menghitung panjangnya. JWT, banyak token API, dan sebagian nama file memakai Base64URL. Untuk mengubah Base64 standar menjadi Base64URL, ganti + dengan -, / dengan _, lalu hapus tanda = di akhir; untuk mengembalikannya, balik penggantian itu dan tambahkan = sampai panjangnya kelipatan empat.

Percent-Encoding di URL

URL hanya boleh berisi sekumpulan karakter terbatas, dan sebagian di antaranya membentuk struktur alamat: / dan ? memisahkan path dan kueri, & dan = memisahkan parameter, # memulai fragmen. Jika sebuah nilai berisi salah satu karakter ini, atau apa pun di luar ASCII, nilai itu di-percent-encode: setiap byte dari bentuk UTF-8-nya ditulis sebagai % diikuti dua digit heksadesimal. “café” menjadi caf%C3%A9, karena é adalah dua byte C3 A9.

Huruf, angka, dan - . _ ~ tidak pernah perlu di-encode. Karakter berikut paling sering menimbulkan masalah:

KarakterHasil encodingMengapa penting
spasi%20Tidak diizinkan di URL
&%26Akan memulai parameter baru
=%3DAkan mengakhiri nama parameter
?%3FAkan memulai kueri
#%23Akan memulai fragmen, yang tidak dikirim ke server
/%2FAkan menambah segmen path
+%2BDibaca sebagai spasi dalam data formulir
%%25Akan memulai urutan escape

Encode setiap nilai secara terpisah, lalu susun URL-nya. Di JavaScript, encodeURIComponent melakukannya untuk satu nilai dan juga meng-encode / ? & = #, sedangkan encodeURI ditujukan untuk alamat lengkap dan membiarkan karakter itu apa adanya. Memakai encodeURI untuk satu nilai adalah penyebab umum string kueri yang rusak.

Tanda Plus, Spasi, dan Encoding Ganda

Formulir HTML mengirim kolomnya sebagai application/x-www-form-urlencoded, di mana spasi menjadi +. Dalam sintaks URL umum, + hanyalah tanda plus. Jadi pencarian “C++” yang dikirim sebagai q=C++ tiba di server yang mendekode data formulir sebagai “C” diikuti dua spasi; seharusnya dikirim sebagai q=C%2B%2B. Saat Anda mendekode string kueri secara manual, cari tahu dulu aturan mana yang menghasilkannya.

Encoding ganda terjadi saat nilai yang sudah di-encode di-encode lagi: %20 menjadi %2520, karena % itu sendiri menjadi %25. Jika Anda melihat %25 diikuti dua digit heksadesimal di URL, ada bagian rantai yang meng-encode dua kali; dekode sekali dan cari di mana langkah tambahan itu terjadi.

Isi Sebuah JWT

JSON Web Token (JWT) membawa klaim, seperti siapa penggunanya dan sampai kapan token berlaku, dari sistem yang menerbitkannya ke sistem yang menerimanya. Bentuk bertanda tangan yang umum terdiri dari tiga bagian Base64URL yang dipisahkan titik: header, payload, dan tanda tangan. Setelah didekode, dua bagian pertama adalah JSON biasa:

Header:  {"alg": "HS256", "typ": "JWT"}
Payload: {"sub": "user-42", "role": "editor", "iat": 1767225600, "exp": 1767229200}

Standar (RFC 7519) mendefinisikan beberapa klaim terdaftar; aplikasi menambahkan klaimnya sendiri, seperti role di atas.

KlaimArti
issPenerbit: siapa yang membuat token
subSubjek: biasanya ID pengguna atau akun
audAudiens: layanan yang menjadi tujuan token
exp, nbf, iatKedaluwarsa, tidak sebelum, diterbitkan: waktu Unix dalam detik
jtiID token, untuk mendeteksi pemakaian ulang atau mencabut satu token

Karena payload hanya di-encode, siapa pun yang memegang token dapat membacanya. Jangan masukkan data pribadi dan rahasia, dan jaga token tetap kecil: token ikut di setiap permintaan, dan banyak server membatasi ukuran header permintaan.

Bertanda Tangan Bukan Berarti Rahasia: Cara JWT Diperiksa

Tanda tangan dihitung dari header dan payload. Dengan HS256, penerbit dan penerima berbagi satu rahasia dan memakai HMAC dengan SHA-256. Dengan RS256 atau ES256, penerbit menandatangani dengan kunci privat dan penerima memeriksa dengan kunci publik pasangannya, sehingga penerima tidak bisa membuat token sendiri.

Server yang menerima token harus memverifikasi tanda tangan dengan algoritme dan kunci yang diharapkan, serta memeriksa exp, nbf, iss, dan aud, sebelum memercayai klaim apa pun. Sekadar mendekode, seperti yang dilakukan alat LeedyBox, melewatkan semua itu: alat itu menunjukkan isi token, bukan apakah token itu asli. Pustaka juga harus menolak algoritme “none”, yang menandai token tanpa tanda tangan, kecuali token tanpa tanda tangan memang diharapkan. Jika isinya sendiri harus disembunyikan, token dienkripsi (JWE) dan kemudian terdiri dari lima bagian yang tidak bisa dibaca tanpa kunci.

Masalah Umum dan Solusinya

GejalaKemungkinan penyebabSolusi
Base64 didekode menjadi teks acakDatanya biner, atau teks dengan encoding lainPeriksa apa yang di-encode; simpan data biner sebagai file
“Karakter tidak valid” saat mendekodeAwalan data:, tanda kutip, atau alfabet Base64URLHapus semua sebelum koma; pakai decoder yang menerima - dan _
Parameter tiba terpotongAda & atau # yang belum di-encode di dalam nilaiEncode setiap nilai dengan encodeURIComponent
Ada %2520 di URLNilai di-encode dua kaliEncode sekali saja, di tempat URL disusun
Token ditolak padahal exp masih di masa depanAudiens atau penerbit salah, selisih jam, atau kunci berbedaBandingkan aud, iss, dan kunci tanda tangan dengan yang diharapkan server
Tanggal kedaluwarsa ribuan tahun lagiexp ditulis dalam milidetik, bukan detikSimpan exp, nbf, dan iat dalam detik

Pertanyaan Umum

Apakah Base64 bisa melindungi kata sandi atau kunci API?

Tidak. Siapa pun dapat membalik Base64 dalam sedetik. Kredensial yang di-encode Base64, misalnya di file konfigurasi atau URL, sama terbukanya dengan teks biasa.

Bolehkah saya memasukkan data pribadi ke payload JWT?

Sebaiknya jangan. Siapa pun yang memegang token dapat membaca payload, termasuk ekstensi browser, log, dan proxy yang melihat permintaan. Masukkan ID ke token dan ambil detailnya di server.

Apakah encoding URL melindungi dari serangan injeksi?

Hanya dalam arti bahwa nilai tidak bisa merusak struktur URL. Server tetap harus memvalidasi dan meng-escape nilai yang sudah didekode sesuai tempat penggunaannya, seperti SQL, HTML, atau perintah shell.

Mengapa string Base64 saya lebih panjang dari filenya?

Setiap tiga byte menjadi empat karakter, jadi teksnya sekitar 33% lebih besar, dan jeda baris menambah sedikit lagi. Untuk file besar, mengirim byte secara langsung lebih efisien daripada Base64.