- Encoding Base64 adalah metode yang mengubah data biner menjadi teks ASCII, sehingga mengurangi kemungkinan data disalahartikan selama proses penyimpanan atau transmisi
- Ini bukan enkripsi, melainkan perubahan cara representasi, sehingga data yang sudah di-encode dapat dengan mudah dikembalikan menjadi teks asli atau data file semula
- Karena 64 karakter dapat direpresentasikan dengan 6 bit, satu karakter Base64 memuat data 6 bit, dan 3 byte (24 bit) diubah menjadi empat karakter Base64
- Berguna di lingkungan yang rawan bermasalah jika memakai biner mentah, seperti Data URLs di HTML, pengiriman biner melalui email, jaringan yang berpusat pada teks, atau URL
- Berbagai bahasa dan alat seperti Ruby, C#, PHP, JavaScript, serta perintah
base64di terminal menyediakan fungsi encoding dan decoding
Apa yang diubah oleh Base64
- Encoding Base64 mengonversi data biner menjadi teks, lebih tepatnya teks ASCII
- Hasilnya hanya menggunakan 64 karakter berikut
A-Za-z0-9+/
- Kumpulan karakter ini digunakan sebagai kumpulan karakter aman untuk menghindari situasi ketika karakter seperti
<,>, dan\ndisalahartikan oleh komputer atau program lama - Jika
"Ruby on Rails"di-encode ke Base64, hasilnya adalahUnVieSBvbiBSYWlscw== - Base64 bukan enkripsi
- Data yang sudah di-encode dapat dengan mudah dikembalikan menjadi teks asli
- Base64 tidak menyembunyikan data, hanya mengubah representasinya
Situasi penggunaan Base64
- Data URLs memungkinkan data file seperti gambar dimasukkan langsung ke dalam HTML, dan dalam kasus ini digunakan teks yang di-encode dengan Base64
- Format contohnya adalah
data:[<mime type>][;charset=<charset>][;base64],<encoded data> - Dalam email, Base64 telah digunakan untuk memuat data biner dengan aman bahkan di lingkungan tempat server dapat mengubah baris baru
- Saat memasukkan data gambar langsung ke dalam sumber HTML, encoding diperlukan agar karakter seperti
<dan>tidak ditafsirkan sebagai tag - Base64 juga dapat digunakan saat menyimpan atau mengirim data biner melalui jaringan yang dirancang untuk memproses data teks atau US-ASCII
- Base64 juga dapat digunakan saat menyampaikan data yang berisi karakter yang sulit dimasukkan ke dalam URL
- Encoding keluarga Base dimanfaatkan di berbagai aplikasi karena memungkinkan objek ditangani dengan editor teks
Algoritme encoding
- Encoding Base64 berjalan dengan urutan berikut
- Mengonversi teks menjadi representasi biner
- Membagi bit menjadi kelompok 6 bit
- Mengonversi setiap kelompok 6 bit menjadi angka desimal dari 0 hingga 63
- Mengubah angka tersebut menjadi karakter yang sesuai dalam alfabet Base64
- Jika grup terakhir kekurangan bit,
=atau==dapat ditambahkan sebagai padding - Untuk merepresentasikan 64 karakter diperlukan 6 bit
2^6 = 64- Satu angka Base64 merepresentasikan data 6 bit
- Satu byte berisi 8 bit, dan kelipatan persekutuan terdekat dari 8 dan 6 adalah 24
- 24 bit adalah 3 byte
- 24 bit direpresentasikan sebagai empat angka Base64 masing-masing 6 bit
Contoh encoding “Akshay”
"Akshay", setelah setiap karakter diubah menjadi angka ASCII lalu dikonversi ke biner, menjadi sebagai berikut01000001 01101011 01110011 01101000 01100001 01111001
- Jika ini dibagi menjadi kelompok 6 bit, hasilnya sebagai berikut
010000 010110 101101 110011 011010 000110 000101 111001
- Jika setiap kelompok diubah menjadi desimal, diperoleh nilai berikut
16 22 45 51 26 6 5 57
- Jika dikonversi dengan alfabet Base64, hasilnya menjadi karakter berikut
Q W t z a G F 5
- Jadi representasi Base64 dari
"Akshay"adalahQWtzaGF5 - Dengan cara yang sama, file seperti gambar, PDF, teks, dan video juga dapat diubah menjadi biner lalu di-encode ke Base64 agar dapat disimpan atau dikirim sebagai teks ASCII
Penggunaan dalam bahasa dan alat
- Ruby menangani encoding dan decoding melalui modul
Base64Base64.encode64("Ruby on Rails")Base64.decode64(encoded)
- C# mengubah string menjadi array byte lalu melakukan encoding dengan
Convert.ToBase64String, dan decoding denganSystem.Convert.FromBase64String - PHP menyediakan fungsi tingkat atas
base64_encodedanbase64_decode - JavaScript melakukan encoding dengan
btoa()dan decoding denganatob() - Di terminal, encoding dan decoding juga dapat dilakukan dengan perintah
base64echo "akshay" | base64menghasilkanYWtzaGF5Cg==echo "YWtzaGF5Cg==" | base64 -dmenghasilkanakshay
1 komentar
Komentar Hacker News
Terima kasih karena menegaskan bahwa ini bukan mengenkripsi teks. Banyak developer junior terlambat belajar perbedaan bahwa enkripsi memerlukan nilai rahasia agar bisa dibalik, hashing tidak bisa dibalik, dan encoding selalu bisa dibalik dengan mudah, lalu akhirnya terjebak karenanya
Perlu juga dipahami bahwa meskipun output terlihat acak, entropinya tetap sama dengan input. Artinya, jangan mencoba membuat kata sandi lebih kuat dengan meng-encode-nya ke Base64
Jika kata sandi dibuat sepenuhnya secara acak, encoding Base64 tidak memberi efek apa pun. Tetapi jika kata sandi dibuat dengan skema berentropi rendah seperti kata kamus atau pola yang mudah diingat, penyerang harus mengatur password cracker yang cukup pintar agar juga mempertimbangkan aturan encoding Base64, sehingga setidaknya ada satu operasi tambahan per percobaan
Tentu saja, skema kata sandi seperti ini tidak seharusnya dipakai. Kata sandi ala “correct horse battery staple” menurut saya sudah cukup
Hashing punya banyak tujuan selain keamanan, jadi ada bermacam-macam library hash. Jika Anda akan memakai hash untuk tujuan keamanan atau kriptografi, gunakan hash yang memang dirancang untuk tujuan itu. Hash CRC memang cepat, tetapi tidak baik dipakai untuk kata sandi pengguna
Salah satu hal menarik tentang Base64 adalah, jika Anda mulai dari suatu string lalu terus meng-encode-nya berulang kali, bagian awal hasilnya perlahan akan konvergen ke fixed point. Ini juga bisa dicek dengan Bash
Saya menemukannya secara tidak sengaja lebih dari 10 tahun lalu dan men-tweet-nya seperti teka-teki [1], lalu seseorang menulis posting blog tentang itu dan mempostingnya di sini juga, tetapi tidak banyak diskusi [2]. Saat orang lain mempostingnya ke Reddit /r/compsci, di sana justru ada diskusi produktif yang mengoreksi posting blog tersebut [3]. Blog aslinya sekarang sudah tidak ada, tetapi salinannya masih tersimpan di Internet Archive [4]
[1] https://twitter.com/p4bl0/status/298900842076045312
[2] https://news.ycombinator.com/item?id=5181256
[3] https://www.reddit.com/r/compsci/comments/18234a/the_base64_...
[4] https://web.archive.org/web/20130315082932/http://fmota.eu/b...
Saat meng-encode dengan Bash, Anda harus memakai opsi
-n:$ echo -n "abcde" |base64Tanpa
-n,echomenambahkan karakter baris baru di akhir string, dan karakter itu ikut di-encodeechodan pakai printf saja. https://linux.die.net/man/1/printfAda juga base64URL, yang melakukan encoding dengan karakter ASCII lain yang aman untuk URL. Beberapa developer bahkan menyebut BASE64URL hanya sebagai base64, dan ini bisa menimbulkan masalah bagi orang yang tidak tahu
https://datatracker.ietf.org/doc/html/rfc4648#section-5
~dan.bukan karakter huruf, jadi saat nilainya di-double-click, seluruh string tidak terseleksi. Dalam banyak kasus copy-paste, ini menimbulkan gesekan yang tidak perluEncoding Base62 (
0-9A-Za-z) hampir sama efisiennya dengan base64url, tetap aman untuk URL, dan lebih mudah untuk copy-paste. Jika ingin mengurangi ambiguitas saat dibaca manusia, Anda bisa turun ke Base58, tetapi biasanya kalau sudah memakai encoding BaseXX, panjangnya cukup besar sehingga copy-paste adalah hal yang umum, jadi ini bukan masalah besarhttps://en.wikipedia.org/wiki/Base62
String Base64 yang memiliki padding selalu panjangnya kelipatan 4, jadi jika menerima string yang bukan kelipatan 4, kita bisa tahu berapa banyak padding yang semula dibutuhkan dan juga bisa menentukan bagaimana 3 byte terakhir harus di-decode
Karena itu, saya agak bingung mengapa Base64 sejak awal memerlukan padding
==Setiap kali ada pembahasan tentang konversi basis, saya tanpa malu-malu mempromosikan konverter basis arbitrer ini: https://convert.zamicol.com
base64 di bawah “useful alphabets” adalah basis “alami” yang memakai pembagian berulang menurut radix, sedangkan metode konversi “bucket” ala RFC ada di bawah extras
Jika Anda meng-encode sesuatu dan manusia harus mengetiknya langsung, saya merekomendasikan https://en.wikipedia.org/wiki/Base32
Tidak ada yang lebih menjengkelkan daripada bingung apakah itu
latau1,oatauOatau0, gara-gara font yang burukJika ingin sedikit lebih ketat, lebih akurat mengatakan bahwa Base64 meng-encode data biner ke subset ASCII, bukan ke seluruh karakter ASCII
ASCII memiliki 128 code point, dengan 95 karakter yang bisa dicetak dan 33 karakter kontrol, sedangkan Base64 hanya memakai 64 di antaranya, atau 65 jika padding ikut dihitung
Tulisan itu tidak membahas dengan rinci tujuan padding
=/==, dan juga tidak menunjukkan dengan contoh bagaimana data yang tidak bisa dibagi pas menjadi grup 6-bit diprosesSepertinya saya sudah paham kira-kira, tapi ingin memastikannya. Akan bagus kalau bisa dijawab secara singkat namun lengkap: kapan
=dipakai dan kapan==, apakah selalu ditambahkan atau ada kasus tidak dipakai, bagaimana tepatnya bit sisa pada string seperti"5byte"diproses, dan hal apa yang perlu diperhatikan saat decodingSatu karakter Base64 merepresentasikan 6 bit, jadi satu blok data 3 byte berkorespondensi dengan blok 4 karakter Base64. Karena itu, data Base64 nyaman diproses per 4 karakter
=adalah padding yang ditambahkan sebanyak 0, 1, atau 2 buah sesuai kebutuhan agar panjang string hasil encoding menjadi kelipatan 4. Misalnya,"543210"menjadi"543210==","6543210"menjadi"6543210=", dan"76543210"tidak memerlukan padding. Tidak akan pernah ada kebutuhan 3 buah=, karena bahkan 1 byte data tetap membutuhkan minimal 2 karakter Base64Bit sisa cukup diisi dengan 0, dan decoder bisa membuangnya karena tahu bit tersebut tidak cukup untuk membentuk 1 byte utuh. Dalam kebanyakan kasus modern, padding bukan keharusan mutlak melainkan lebih ke konvensi. Artikel Wikipedia cukup rinci: https://en.wikipedia.org/wiki/Base64
Karakter padding di akhir stream, file, atau string sebenarnya tidak wajib secara ketat karena bisa disimpulkan dari panjang data yang sudah diproses
Namun cara menangani padding cukup subtil, dan perbedaan itu memunculkan variasi implementasi yang menarik: https://eprint.iacr.org/2022/361.pdf
Pada akhirnya, encoding dilakukan dalam unit 24 bit. Saat data berakhir, sisa bagian 24 bit diisi dengan
=alih-alihA, karenaAsebagai data berarti000000. Saya juga harus membaca keseluruhannya dua kali untuk memahaminyaShader encoder Base64 saya ada di sini: https://github.com/Rezmason/excel_97_egg/blob/main/glsl/base...
Saya berhasil memangkasnya menjadi sekitar 13 baris GLSL: https://github.com/Rezmason/excel_97_egg/blob/main/glsl/base...
Dipakai di Cursed Mode pada side project saya, yang merender framebuffer WebGL sebagai BMP warna terindeks 640x480 yang di-encode Base64 sekitar 15 kali per detik: https://rezmason.github.io/excel_97_egg/?cursed=1
Begitu mulai menggali lebih dalam, ada detail tambahan yang menarik, dan variasi dari detail-detail itu ternyata sangat banyak
Jika panjang data masukan bukan kelipatan tepat dari 3 byte, maka 1 byte atau 2 byte terakhir diencode menjadi 2 atau 3 karakter Base64. Karena satu karakter Base64 adalah 6 bit, maka untuk merepresentasikan 8 bit atau 16 bit dipakai 12 bit atau 18 bit, sehingga muncul 4 bit atau 2 bit ekstra yang sebenarnya tidak meng-encode apa pun
RFC mewajibkan encoder menyetel bit-bit itu ke 0, tetapi untuk decoder hanya disebutkan bahwa ia boleh menolak masukan jika bit-bit itu bukan 0. Dalam praktiknya, hampir tidak ada implementasi yang menolak secara default, dan setahu saya hanya Ruby, Rust, dan Go yang bisa diatur agar gagal pada masukan seperti itu. Python punya opsi
validate, tetapi bit-bit tersebut tidak diperiksaPerbedaan besar lain adalah penanganan spasi dan karakter non-Base64. Cukup mengejutkan, banyak implementasi termasuk Python diam-diam mengabaikan karakter sewenang-wenang dalam input. Ini bisa bermasalah jika alfabet yang dipilih salah; misalnya di Python,
base64.standard_b64decode(base64.urlsafe_b64encode(b'\xFF\xFE\xFD\xFC'))tidak menghasilkan error, melainkan diam-diam memberi keluaran yang salahMenarik juga bahwa encoder Base64 Ruby menyisipkan newline setiap 60 karakter. Di luar PEM, tidak ada encoding standar yang meminta baris sependek itu, dan PEM sendiri justru mensyaratkan panjang baris tepat 64 karakter, jadi ini pilihan yang cukup aneh
Saya menulis artikel yang merangkum perbedaan antar bahasa pemrograman dan beberapa library JavaScript [1], dan juga sedang mengerjakan upaya menambahkan Base64 yang lebih baik ke JS [2]
[1] https://gist.github.com/bakkot/16cae276209da91b652c2cb3f612a...
[2] https://github.com/tc39/proposal-arraybuffer-base64