Penggunaan token berupa alat kecil
semacam kalkulator untuk mengamankan transaksi internet banking kini sudah
menjadi hal yang wajib. Token ini menjadi faktor tambahan dalam otentikasi yaitu
untuk membuktikan bahwa anda adalah benar-benar pengguna yang sah. Mungkin ada
yang bertanya-tanya bagaimana cara kerja token seperti yang dipakai situs
internet banking? Bagaimana alat kecil seperti kalkulator itu bisa menghasilkan
angka yang juga diketahui oleh server internet banking, padahal alat itu tidak
terbubung dengan server. Dalam artikel ini saya akan menjelaskan cara kerja
token internet banking, dan dalam artikel berikutnya saya akan membuat token
berbasis software dan website sederhana yang akan mensimulasikan internet
banking.
Authentication Method
Otentikasi
bertujuan untuk membuktikan siapa anda sebenarnya, apakah anda benar-benar
orang yang anda klaim sebagai dia (who you claim to be). Ada banyak cara untuk
membuktikan siapa anda. Metode otentikasi bisa dilihat dalam 3 kategori metode:
- Something You Know
Ini adalah metode otentikasi yang paling umum. Cara ini
mengandalkan kerahasiaan informasi, contohnya adalah password dan PIN. Cara ini
berasumsi bahwa tidak ada seorangpun yang mengetahui rahasia itu kecuali anda
seorang.
- Something You Have
Cara ini biasanya merupakan faktor tambahan untuk membuat
otentikasi menjadi lebih aman. Cara ini mengandalkan barang yang sifatnya unik
contohnya adalah kartu magnetik/smartcard, hardware token, USB token dan
sebagainya. Cara ini berasumsi bahwa tidak ada seorangpun yang memiliki barang
tersebut kecuali anda seorang.
- Something You Are
Ini adalah metode yang paling jarang diapakai karena faktor
teknologi dan manusia juga. Cara ini mengandalkan keunikan bagian-bagian tubuh
anda yang tidak mungkin ada pada orang lain seperti sidik jari, suara atau
sidik retina. Cara ini berasumsi bahwa bagian tubuh anda seperti sidik jari dan
sidik retina, tidak mungkin sama dengan orang lain.
Lalu
bagaimana dengan metode otentikasi tradisional seperti tanda tangan di atas
materai? Masuk ke kategori manakah cara itu dari ketiga metode di atas? Saya
pikir tidak ada yang cocok, karena itu saya tambahkan satu lagi yaitu “Something
You Can“. Cara ini berasumsi bahwa tidak ada orang lain di dunia ini
yang bisa melakukan itu selain anda. Memang otentikasi dengan tanda tangan
dibangun di atas asumsi itu, tidak ada yang bisa menuliskan tanda tangan anda
kecuali anda. Walaupun pada kenyataannya ada saja orang yang bisa meniru tanda
tangan anda dengan sangat baik, namun walaupun menyadari fakta tersebut tanda
tangan di atas kertas tetap diakui sebagai bukti otentik atas siapa anda.
Two
Factor Authentication
Pada
aplikasi yang kritis dan sensitif seperti transaksi keuangan, satu metode
otentikasi saja tidak cukup. Oleh karena itu muncul istilah 2FA (Two Factor
Authentication) yang merupakan sistem otentikasi yang menggunakan 2 faktor
(metode) yang berbeda. Empat metode otentikasi yang sudah saya jelaskan
sebelunya dapat dikombinasikan untuk meningkatkan keamanan, salah satu
contohnya adalah dengan kombinasi “something you have” berupa kartu ATM dengan
“something you know” berupa PIN. Kombinasi ini merupakan kombinasi yang paling
banyak dipakai.
Contoh
kasus lain adalah ketika anda berbelanja di pasar modern dan membayar dengan
kartu, tanpa disadari anda telah memakai lebih dari satu faktor otentikasi.
Faktor yang pertama adalah “Something You Have” yaitu kartu debit/kredit anda.
Faktor kedua adalah “Something You Know”, ketika anda diminta memasukkan PIN ke
dalam mesin EDC. Bahkan mungkin ada faktor ketiga yaitu “Something You Can”,
ketika anda diminta menanda-tangani nota pembayaran yang dicetak mesin EDC.
Internet
banking juga menggunakan two factor authentication dengan mengombinasikan
“something you know” berupa password dan “something you have” berupa hardware
token (keyBCA atau Token Mandiri).
Password
yang Dikeluarkan Token Internet Banking
Pada
umumnya ada dua mode pemakaian token internet banking:
- Mode Challenge/Response (C/R)
Ini adalah mode yang paling sering dipakai ketika
bertransaksi. Dalam mode ini server memberikan challenge berupa sederetan
angka. Angka tersebut harus dimasukkan kedalam mesin token untuk mendapatkan
jawaban (response). Kemudian pengguna memasukkan angka yang muncul pada
tokennya ke dalam form di situs internet banking. Token akan mengeluarkan kode
yang berbeda-beda walaupun dengan challenge code yang sama secara periodik
tergantung waktu ketika challenge dimasukkan ke dalam token.
- Mode Self Generated (Response Only)
Dalam mode ini server tidak memberikan tantangan (challenge)
apapun. Token pengguna bisa langsung mengeluarkan sederetan angka tanpa harus
memasukkan challenge. Seperti mode C/R, token juga mengeluarkan kode yang
berbeda-beda secara periodik tergantung waktu ketika token diminta untuk
menghasilkan kode self generated.
Sebenarnya
jawaban yang diberikan oleh token baik dalam mode C/R maupun Self
Generated(resopnse only) tidak lain adalah password juga. Namun berbeda dengan
password yang anda pakai untuk login, password yang dihasilkan token ini
memiliki keterbatasan untuk alasan keamanan, yaitu:
- Hanya boleh dipakai 1 kali
Ini disebut dengan OTP (One Time Password). Setelah suatu
password dipakai, maka password yang sama tidak bisa lagi dipakai untuk kedua
kalinya. Dengan cara ini tidak ada gunanya menyadap password yang dihasilkan
token karena password tersebut tidak bisa dipakai lagi. Namun bila password
tersebut di-intercept sehingga tidak pernah sampai ke server, maka password
tersebut masih berharga karena di mata server, password itu belum pernah
dipakai.
- Hanya boleh dipakai dalam rentang waktu yang terbatas
Password yang dihasilkan token memiliki umur yang sangat
terbatas, mungkin antara 3-6 menit bila umurnya habis maka password itu tidak
bisa dipakai, walaupun belum pernah dipakai. Nanti akan saya jelaskan mengapa
password token memerlukan umur, waktu merupakan unsur yang sangat kritikal
dalam sistem ini.
- Hanya boleh dipakai dalam konteks sempit
Bila password/PIN yang dipakai untuk login adalah password
yang bebas konteks, dalam arti dengan berbekal password itu, anda bisa
melakukan banyak hal, mulai dari melihat saldo, mengecek transaksi dan
sebagainya. Namun password yang dihasilkan token, hanya bisa dipakai dalam konteks
sempit, contohnya password yang dipakai untuk mengisi pulsa ke nomor
08123456789, tidak bisa dipakai untuk melakukan transfer dana.
Terbatasnya konteks ini disebabkan karena untuk melakukan
transaksi dibutuhkan password yang diikat oleh challenge dari server, sehingga
password tersebut tidak bisa dipakai untuk transaksi lain yang membutuhkan
challenge code yang berbeda. Contohnya bila challenge yang diberikan server
adalah 3 digit terakhir dari nomor handphone (untuk transaksi isi pulsa), atau
3 digit terakhir nomor rekening tujuan (untuk transaksi transfer). Maka
password yang dihasilkan token untuk transaksi isi pulsa ke nomor
0812555111222, akan valid juga untuk transaksi transfer uang ke rekening
155887723120222. Sebab kebetulan kedua transaksi tersebut membutuhkan password
yang diikat oleh challenge code yang sama, yaitu 222 (diambil dari 3 digit
terakhir).
Konteks ini hanya berlaku bila password dihasilkan dalam
mode C/R. Password yang dihasilkan dalam mode Self Generated, bisa dipakai
dalam transaksi apa saja yang tidak meminta password dengan challenge code.
Jadi
bisa disimpulkan bahwa password yang dikeluarkan token bersifat:
- Selalu berubah-ubah secara periodik
- Memiliki umur yang singkat
- Hanya bisa dipakai 1 kali
- Terbagi dalam ada dua jenis, yaitu:
- Password kontekstual yang terikat oleh challenge code dalam mode challenge/response.
- Password bebas konteks yang dihasilkan dalam mode self generated.
Proses
Otentikasi
Seperti password pada umumnya,
syarat agar otentikasi berhasil adalah:
password yang dikirimkan client =
password yang disimpan di server
Dengan
alasan keamanan jarang sekali server menyimpan password user dalam bentuk
plain-text. Biasanya server menyimpan password user dalam bentuk hash sehingga
tidak bisa dikembalikan dalam bentuk plain-text. Jadi syarat otentikasi
berhasil di atas bisa diartikan sebagai hasil penghitungan hash dari password
yang dikirim klien harus sama dengan nilai hash yang disimpan dalam server.
Perhatikan gambar di bawah ini untuk lebih memahami.
Penggunaan Salt
Untuk
menghindari brute-force attack terhadap hash yang disimpan di server, maka
sebelum password user dihitung nilai hashnya, terlebih dahulu ditambahkan
string acak yang disebut dengan salt. Perhatikan contoh berikut, bila password
user adalah “secret”, maka sebelum dihitung nilai hashnya, password ditambahkan
dulu salt berupa string acak “81090273″ sehingga yang dihitung nilai hashnya
adalah “secret81090273″ bukan “secret”.
Perhatikan
bahwa nilai MD5(“secret81090273″) adalah 894240dbe3d2b546c05a1a8e9e0df1bc
sedangkan nilai MD5(“secret”) adalah 5ebe2294ecd0e0f08eab7690d2a6ee69. Bila
tanpa menggunakan salt, maka attacker yang mendapatkan nilai hash
5ebe2294ecd0e0f08eab7690d2a6ee69 bisa menggunakan teknik brute force attack
atau rainbow table untuk mendapatkan nilai password dalam plain-text. Salah
satu contoh database MD5 online yang bisa dipakai untuk crack md5 adalah http://gdataonline.com/seekhash.php . Dalam situs
tersebut coba masukkan nilai 5ebe2294ecd0e0f08eab7690d2a6ee69, maka situs
tersebut akan memberikan hasil “secret”. Hal ini disebabkan karena situs
tersebut telah menyimpan pemetaan informasi
secret<=>5ebe2294ecd0e0f08eab7690d2a6ee69.
Penambahan
salt “81090273″ membuat nilai hash menjadi 894240dbe3d2b546c05a1a8e9e0df1bc.
Bila nilai ini dimasukkan dalam situs tersebut, dijamin tidak akan ada dalam
databasenya bahwa nilai hash tersebut adalah “secret81090273″. Dan karena nilai
salt ini dibangkitkan secara random, maka tiap user memiliki nilai salt yang
berbeda sehingga tidak mungkin attacker bisa membangun database pemetaan antara
plaintext dan hash secara lengkap.
Dengan
penggunaan salt, maka database pengguna dalam server akan tampak seperti ini:
Username
|
Salt
|
Password
Hash
|
budi
|
81090273
|
894240dbe3d2b546c05a1a8e9e0df1bc
|
Field
salt diperlukan ketika melakukan otentikasi. Password yang dikirimkan user akan
ditambahkan dulu dengan nilai salt ini baru kemudian dihitung nilai hashnya.
Nilai hash hasil perhitungan tersebut akan dibandingkan dengan field Password
Hash yang ada di kolom sebelahnya. Bila sama, maka otentikasi berhasil,
bila tidak sama, berarti otentikasi gagal. Secara prinsip sama saja dengan
gambar di atas, hanya ditambahkan satu langkah yaitu penambahan salt sebelum
dihitung nilai hashnya.
Pembangkitan
One Time Password (OTP) Token Internet Banking
Apa
yang saya jelaskan sebelumnya menjadi dasar dari apa yang akan saya jelaskan
berikut ini. Bagaimana cara token menghasilkan sederetan angka sebagai OTP yang
bisa diotentikasi oleh server? Ingat bahwa syarat agar otentikasi berhasil
adalah password yang dikirim klien harus sama dengan yang disimpan di server.
Ingat juga bahwa password yang dihasilkan token selalu berubah-ubah secara
periodik. Bagaimana apa yang dihasilkan alat itu bisa sinkron dengan server?
Padahal alat tersebut tidak terhubung dengan server, bagaimana server bisa tahu
berapa nilai yang dihasilkan token? Jawabannya adalah dengan waktu.
Sebelumnya sudah saya sebutkan bahwa waktu adalah elemen yang sangat penting
dalam sistem ini. Server dan token dapat sinkron dengan menggunakan waktu
sebagai nilai acuan.
OTP
dalam Mode Self Generated (Response Only)
Saya
akan jelaskan mulai dari pembangkitan OTP dalam mode self generated atau response
only. Sebelumnya tentu saja, server dan token harus menyepakati sebuah nilai
awal rahasia (init-secret atau secret key). Nilai awal ini disimpan (ditanam)
dalam token device dan disimpan juga dalam database di sisi server.
Ketika
pada suatu waktu tertentu token diminta menghasilkan OTP tanpa challenge code,
inilah yang dilakukan token:
- Mengambil waktu saat ini dalam detik berformat EPOCH (jumlah detik sejak 1 Januari 1970), biasanya dalam granularity 10 detik, sehingga nilai EPOCH dibagi 10.
- Menggabungkan init-secret dengan waktu saat ini dari langkah 1.
- Menghitung nilai hash gabungan init-secret dan waktu dari langkah 2.
Nilai
hash dari langkah 3 inilah yang menjadi OTP. Namun biasanya OTP diambil dari
beberapa karakter/digit di awal hash.
Sebenarnya
yang saya jelaskan di atas hanyalah penyederhanaan saja, proses sebenarnya
lebih kompleks dari yang di atas. Prosedur di atas adalah penyederhanaan dari
keyed-hash atau HMAC (hash-based message authentication code), fungsi hash
dengan tambahan masukan berupa secret key.
Bagaimana
cara server melakukan otentikasi? Caranya mirip dengan yang dilakukan token,
yaitu dengan menghitung nilai hash gabungan init-secret dengan waktu saat ini
dan mengambil beberapa digit di awal sebagai OTP. Bila OTP yang dikirim user
sama dengan OTP yang didapatkan server dari perhitungan hash, maka otentikasi
berhasil.
Namun
ada sedikit catatan yang harus diperhatikan terkait waktu. Untuk memberikan
toleransi perbedaan waktu antara token dan server, dan juga jeda waktu dari
sejak server meminta password sampai user meminta token membangkitkan token,
maka server harus memberikan toleransi waktu.
Ada
tiga kejadian yang perlu diperhatikan waktunya, yaitu:
- Detik ketika server meminta password (OTP) dari user
- Detik ketika token membangkitkan OTP
- Detik ketika server menerima OTP dari user
Perhatikan contoh di bawah ini:
Bila
diasumsikan waktu di server sama persis dengan waktu di token (jam internal
token), maka kita harus perhatikan bahwa pasti akan ada jeda antara kejadian 1,
2 dan 3. Bila pada detik ke-0 server meminta password dari user, karena
lambatnya akses internet, bisa jadi baru pada detik ke-30 user melihat pada
browsernya bahwa dia harus memasukkan OTP dari token. Kemudian baru pada detik
ke-60 token menghasilkan OTP. Pada detik ke-65 user mensubmit nilai OTP
tersebut ke server dan baru tiba di server pada detik ke-90.
Karena
pembangkitan OTP tergantung waktu pada saat OTP dibangkitkan, maka OTP yang
dihasilkan token, adalah OTP pada detik ke-60. Sedangkan server meminta
password dari user sejak detik ke-0. Bagaimana cara server melakukan
otentikasi? Caranya adalah dengan memeriksa seluruh kemungkinan OTP dalam
rentang waktu yang dipandang memadai, misalkan 180 detik.
Bila
sistem menggunakan granularity 10 detik maka server harus menghitung nilai OTP
sejak dari detik ke-0, 10, 20, 30, 40, s/d ke 180 dalam kelipatan 10 detik.
Perhatikan contoh pada gambar di bawah ini. Dalam sistem ini diasumsikan OTP
adalah 6 karakter awal dari MD5 gabungan. Dalam melakukan otentikasi, server
harus membandingkan semua nilai OTP sejak detik ke-0 (dalam contoh ini EPOCH/10
= 124868042) hingga waktu toleransi maksimum.
Dalam contoh di atas bila user mengirimkan OTP
“b1cdb9″ maka otentikasi akan berhasil ketika server menghitung nilai OTP pada
detik ke-60 sejak server meminta OTP dari user.
Ilustrasi di atas hanyalah contoh, pada
kenyataannya ada kemungkinan waktu antara server dan token tidak sama persis
100%, sehingga server terpaksa harus memberikan toleransi waktu tidak hanya ke
depan, namun juga ke belakang. Sebab bisa jadi waktu di server lebih cepat
daripada waktu di token. Sebagai contoh ketika waktu di server menunjukkan
EPOCH/10=124868219, bisa jadi waktu di token baru menunjukkan EPOCH/10=1248682121
(waktu token terlambat 80 detik).
Misalkan waktu toleransi adalah 3 menit, maka
server harus memberikan toleransi 3 menit ke depan dan 3 menit ke belakang
relatif terhadap waktu ketika server menerima OTP dari user dan melakukan
otentikasi. Ingat, waktu toleransi ini relatif terhadap waktu server melakukan
otentikasi. Jadi jika server melakukan otentikasi pada EPOCH/10=600, maka
server harus menghitung seluruh nilai OTP sejak EPOCH/10=420 hingga
EPOCH/10=780.
Ingat penjelasan saya tentang salt sebelumnya.
Kalau dibandingkan dengan OTP ini, maka nilai init-secret adalah sejenis dengan
password plain-text pengguna, sedangkan salt atau tambahannya adalah waktu
(EPOCH/10).
Umur OTP
Sebelumnya sudah saya sebutkan bahwa sifat dari
OTP adalah memiliki umur yang terbatas. Umur ini terkait dengan waktu toleransi
yang diberikan server sebesar X detik ke depan dan X detik ke belakang relatif
terhadap saat server melakukan otentikasi. Bila waktu toleransi adalah 3 menit
(180 detik), maka umur sebuah OTP adalah 3 menit, dalam arti bila server
melakukan otentikasi tidak lebih dari 3 menit sejak OTP dibangkitkan token,
maka OTP tersebut akan dianggap valid oleh server.
OTP dalam Mode Challenge/Response
Pembangkitan dan otentikasi OTP dalam mode C/R
sebenarnya mirip dengan mode self-generated. Bila dalam mode self generated
tambahan (salt) dari init-secret adalah waktu (EPOCH/10), dalam mode C/R ini
salt/tambahannya lebih banyak. Init-secret tidak hanya ditambah dengan waktu,
namun juga ditambah lagi dengan challenge.
Perhatikan gambar di bawah ini. Server melakukan
penghitungan OTP untuk semua detik dalam waktu toleransinya.
Dalam
mode C/R ada field tambahan yang harus digabungkan sebelum dihitung nilai
hashnya, yaitu challenge. Nilai challenge ini diketahui oleh server dan juga
oleh token (ketika user mengetikkan challenge ke token), sehingga baik token
maupun server akan dapat menghitung OTP yang sama sehingga proses otentikasi
dapat berlangsung.