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.
courtesy of "www.unixwiz.net/techtips/iguide-crypto-hashes.html"
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.