| Web Master |
Komponen lainnya adalah server.
Diperlukan web server dan database server, dalam artikel ini saya pakai
XAMPP yang sudah dibundel dengan Apache, PHP dan MySQL.
Spesifikasi One Time Password di Aplikasi Contoh
Dalam aplikasi contoh ini, one time
password didapatkan dengan mengambil 6 karakter pertama hasil
penghitungan hash dengan fungsi MD5. Granularity sistem ini adalah 10
detik, dengan kata lain setiap 10 detik token akan menghasilkan OTP yang
berbeda. Jika anda meminta token mengeluarkan OTP beberapa kali dalam
rentang 10 detik, maka semuanya akan menghasilkan OTP yang sama.
Kemudian baru ketika waktu masuk ke 10 detik berikutnya token akan
menghasilkan OTP yang baru.
Dalam aplikasi contoh ini, umur OTP
adalah 3 menit, artinya server harus menghitung semua OTP dalam time
window 6 menit, yaitu 3 menit ke belakang dan 3 menit ke depan relatif
terhadap waktu ketika server melakukan otentikasi. Konsekuensinya adalah
setiap OTP yang dihasilkan token akan dianggap valid bila belum pernah
dipakai dalam 3 menit sejak OTP dibangkitkan.
Spesifikasi Software Token
Token yang akan saya buat ini nantinya
memiliki fitur yang sama dengan token internet banking pada umumnya.
Pada kondisi normal nilai init-secret sudah ditanam di dalam token
secara hardware, namun dalam token contoh ini tersedia fitur untuk
melakukan inisialisasi nilai init-secret. Init-secret ini harus dicatat
juga di server agar server bisa menghasilkan OTP yang sama dengan token.
Token bisa menghasilkan OTP dalam mode
Challenge/Response maupun dalam mode Response Only (self generated).
Challenge yang diterima oleh token adalah sepanjang 4 digit dan
menghasilkan response sepanjang 6 digit hexadesimal.
Spesifikasi Website
Website dalam aplikasi contoh ini saya
buat dengan PHP. Aplikasi ini terdiri dari 2 file saja, yaitu login.php
dan transfer.php. Login.php digunakan untuk melakukan login dengan
menggunakan response only pin dari token. Sedangkan transfer.php adalah
untuk melakukan transfer uang dengan menggunakan challenge/response pin
dari token.
Aplikasi ini saya pasang pada localhost yang terinstall Apache+MySQL+PHP
dari XAMPP. Sebelum bisa melakukan transfer uang, user harus melakukan
login di URL https://localhost/mytestbank/login.php . Perhatikan URL
tersebut sengaja saya memakai https agar mirip dengan internet banking.
Tentu saja browser anda akan berontak ketika menggunakan https karena
memang saya tidak punya sertifikat yang ditandatangani CA untuk
localhost. Bila anda kesulitan mengonfigurasi browser anda untuk memakai
https tersebut, anda boleh memakai http biasa.
Pada saat login user diminta memasukkan username dan OTP yang dihasilkan
dari token dalam mode response only (self generated). Bila login
berhasil, maka user dialihkan ke halaman
https://localhost/mytestbank/transfer.php . Berbeda dengan halaman
login, pada saat transfer user diminta untuk memasukkan OTP dari token
dalam mode challenge/response. Server memberikan challenge sepanjang 4
digit angka.
Aplikasi ini juga membutuhkan sebuah
tabel MySQL bernama users yang saya masukkan dalam database bernama
mytestbank. Tabel ini digunakan untuk menyimpan informasi pengguna
website. Berikut adalah script SQL untuk membuat tabel users.
CREATE TABLE IF NOT EXISTS `users` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `username` VARCHAR(255) NOT NULL, `initsecret` VARCHAR(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ; |
Agar lebih mudah sebaiknya anda menginstall XAMPP atau WAMP dan menggunakan PhpMyAdmin untuk membuat tabel users tersebut.
Pembuatan Token
Token dibuat dengan Java Mobile (disebut midlet) yang sangat sederhana.
Midlet ini hanya terdiri dari 2 file, yaitu MD5.java dan MobileOTP.java.
Class MD5 adalah library untuk menghitung nilai hash MD5. Sedangkan
class MobileOTP adalah class utama. Karena sourcenya cukup panjang, anda
bisa mendownload sourcenya dalam file zip di sini.
File zip itu bisa langsung anda extract ke dalam folder apps dalam Java
Wireless Toolkit bila ingin menjalankan midlet itu dengan menggunakan
emulator.
Saya akan menjelaskan fungsi utama dari token yaitu membangkitkan OTP
dalam mode Challenge/Response dan mode Response Only. Perhatikan
potongan kode token berikut yang berfungsi untuk membangkitkan OTP dalam
mode Response Only.
now=new Date(); epoch=""+(now.getTime()+((timez-12)*3600000)); epoch=epoch.substring(0,epoch.length()-4); String otp=epoch+secret; MD5 hash=new MD5(otp); otp=hash.asHex().substring(0,6); |
Kode di atas sangat sederhana, diawali dengan mengambil detik EPOCH
sepanjang 9 digit (ini sama dengan EPOCH/10 karena granularitynya adalah
10 detik). Kemudian nilai EPOCH tersebut digabung dengan init-secret.
String gabungan epoch dengan init secret ini dihitung hashnya dengan
MD5. Kemudian 6 karakter pertama dari hash tersebut diambil sebagai OTP
response only (self generated).
Kode berikut ini adalah untuk membangkitkan OTP dalam mode
challenge/response. Kode tersebut sangat mirip dengan potongan kode di
atas hanya perbedaannya adalah adanya challenge yang dalam kode tersebut
ada pada variabel PIN. Gabungan dari epoch, init secret dan challenge
dihitung nilai hashnya dengan MD5, baru kemudian diambil 6 karakter
pertamanya sebagai OTP.
1 2 3 4 5 6 | now=new Date(); epoch=""+(now.getTime()+((timez-12)*3600000)); epoch=epoch.substring(0,epoch.length()-4); otp=epoch+secret+PIN; hash=new MD5(otp); otp=hash.asHex().substring(0,6); |
Bila anda ingin mencobanya di hape anda, pastikan HP anda mendukung
java. Anda bisa mengkopi file JAR aplikasi ini ke memory card anda
dengan bluetooth/USB, atau anda bisa juga mendownload langsung dari
browser hp anda. URL untuk mendownload file JAR midlet ini adalah
http://www.ilmuhacking.com/wp-content/uploads/2009/07/MobileOTP.jar .
Selanjutnya anda tinggal mengikuti petunjuk untuk instalasi aplikasi
seperti biasa. Ingat sebelum dipakai diperlukan langkah inisialisasi
nilai init-secret dengan cara mengetikkan #**# dalam field “CHAL”.
Berikut ini adalah screen capture dari aplikasi tersebut yang diinstall
di HP saya. Dua gambar di bawah ini adalah prosedur inisialisasi
init-secret ketika aplikasi pertama kali dijalankan. Nilai init secret
ini harus dicatat dan disimpan ke dalam tabel user di server.
Gambar di bawah ini adalah screen shot ketika midlet token membangkitkan OTP dalam mode response only.
Gambar di bawah ini adalah screen shot ketika midlet token membangkitkan OTP dalam mode challenge response.
Pembuatan Aplikasi Web
Aplikasi web terdiri dari dua file yaitu login yang menggunakan OTP
dalam mode response only, dan transfer yang menggunakan OTP dalam mode
challenge response. Seperti halnya midlet token, aplikasi ini juga
sangat sederhana. Fungsi utamanya adalah pada fungsi checkCR() dan
checkRO() yang berfungsi untuk melakukan otentikasi dalam mode
Challenge/Response atau Response Only. Berikut adalah isi dari fungsi
checkCR dan checkRO.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | // Check Challenge/Response Mode function checkCR($chal,$otp,$initsecret) { $maxperiod = 3*60; // in seconds = +/- 3 minutes $time=gmdate("U"); for($i = $time - $maxperiod; $i <= $time + $maxperiod; $i++) { $md5 = substr(md5(substr($i,0,-1).$initsecret.$chal),0,6); if($otp == $md5) return(true); } return(false); } // Check Response/Only Mode function checkRO($otp,$initsecret) { $maxperiod = 3*60; // in seconds = +/- 3 minutes $time=gmdate("U"); for($i = $time - $maxperiod; $i <= $time + $maxperiod; $i++) { $md5 = substr(md5(substr($i,0,-1).$initsecret),0,6); if($otp == $md5) return(true); } return(false); } |
Perbedaan kedua fungsi itu hanya pada adanya $chal pada fungsi checkCR()
sedangkan pada fungsi checkRO() yang digabungkan hanya epoch dan
initsecret. Mari kita ulas kedua fungsi tersebut karena inti dari
aplikasi ini ada pada kedua fungsi itu.
Dalam artikel sebelumnya saya sudah menjelaskan mengenai time window
atau toleransi yang diberikan server ketika melakukan otentikasi. Dalam
contoh ini time window yang diberikan server adalah 3 menit ke depan dan
3 menit ke belakang relatif terhadap waktu ketika server melakukan
otentikasi. Waktu (dalam detik EPOCH) ketika server melakukan otentikasi
disimpan pada variabel $time (baris ke-5 dan baris ke-18), sehingga
server harus menghitung semua otp dari $time-180 hingga $time+180 (3
menit ke belakang dan 3 menit ke depan) pada baris ke-6 dan baris-19.
Selanjutnya pada barus ke-8 dan baris ke-21 server menghitung otp dengan
mengambil 6 karakter awal dari fungsi hash gabungan dari
epoch+initsecret dan challenge (khusus untuk checkCR).
Di bawah ini adalah source untuk file login.php. Untuk melakukan
otentikasi, login.php memanggil fungsi checkRO() pada baris ke-12. Namun
untuk memanggil fungsi checkRO() dibutuhkan init secret dari user yang
disimpan dalam tabel users sehingga server harus melakukan query ke
tabel users (baris ke-8). Selanjutnya bila otentikasi berhasil server
akan menyimpan username dan initsecret pada session kemudian mengalihkan
user ke aplikasi transfer (transfer.php).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | <?php session_start(); include("initdb.php"); include("lib.php"); if (isset($_POST["login"])) { $username = addslashes($_POST["username"]); $pin = $_POST["pin"]; $sql = "select initsecret from users where username='$username' "; $res=mysql_query($sql); if ($arr_row=mysql_fetch_array($res)) { $initsecret = $arr_row[0]; $success = checkRO($pin,$initsecret); if ($success) { $_SESSION["username"] = $username; $_SESSION["initsecret"] = $initsecret; header("Location: transfer.php"); } else { $err = "Wrong PIN, Try Again."; } } else { $err = "Wrong PIN, Try Again."; } } ?> <html> <body> <H1>Login Internet Banking MyTestBank</H1> <?php if (isset($err)) echo "<font color=red><B>$err</b></font>"; ?> <form method="post" action=""> <table border=1> <tr> <td>Username</td> <td><input type="text" name="username" /></td> </tr> <tr> <td>Token PIN:</td> <td><input type="text" name="pin" /></td> </tr> <tr> <td colspan=2 align=center><input type="submit" name="login" value="Login" /></td> </tr> </table> </form> </body> </html> |
Di bawah ini adalah source untuk file transfer.php. Untuk melakukan
otentikasi server memanggil fungsi checkCR() pada baris ke-13. Fungsi
checkCR ini membutuhkan init secret, challenge yang diambil dari
session. Kemudian server akan memberikan pesan “Transfer Success” atau
“Wrong PIN” tergantung dari hasil fungsi checkCR().
Pada baris ke-21 dan ke-22 server membangkitkan nilai acak sepanjang 4
digit sebagai challenge. Challenge ini disimpan dalam session agar tidak
bisa dimanipulasi user. Bila challenge disimpan sebagai hidden field
dalam form, maka user bisa bebas mengubah isi challenge itu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <?php session_start(); include("initdb.php"); include("lib.php"); if (!isset($_SESSION["initsecret"])) { header("Location: login.php"); } if (isset($_POST["login"])) { $username = addslashes($_POST["username"]); $pin = addslashes($_POST["pin"]); $initsecret = $_SESSION["initsecret"]; $challenge = $_SESSION["challenge"]; $success = checkCR($challenge,$pin,$initsecret); if ($success) { $msg = "<font color=green>Transfer Success</font>"; } else { $msg = "<font color=red>Wrong PIN</font>"; } } srand(time()); $challenge = sprintf("%04d",(rand()%9999)); $_SESSION["challenge"] = $challenge; ?> <html> <body> <?php if (isset($msg)) echo "<B>$msg</b>"; ?> <h1>Transfer Form</h1> <form method="post" action=""> No Rekening Tujuan: <input type="text" name="norek" /><br/> Jumlah: Rp. <input type="text" name="jumlah" /><br/> Challenge Code: <?= $challenge ?><i>(Masukkan kode ini ke dalam token anda)</i><br/> Token PIN : <input type="text" name="pin" /><i>(Masukkan response dari token anda)</i><br/> <input type="submit" name="login" value="Transfer" /><br/> </form> </body> </html> |
Anda bisa mendownload semua source php di sini.
Test
Sebelum mencoba pertama saya harus menyamakan jam di token (handphone)
dengan jam di server. Setelah sama baru kita uji coba aplikasi ini
dengan skenario berikut:
Nasabah myTestBank ingin memakai aplikasi internet banking myTestBank
untuk mentransfer sejumlah uang. Untuk itu dia baru saja mendownload Midlet Token
dan menginstallnya ke HPnya. Token midlet tersebut diinisialisasi
dengan nilai init secret 369e4a62be0e579a. Setelah mendaftar user
tersebut mendapat username rizki. Untuk menggunakan fasilitas ini dia
harus membuka browser ke URL https://localhost/mytestbank/login.php .
Selain menyamakan jam di token dan di server, init secret di token dan
di server harus sama. Gambar di bawah ini menunjukkan bahwa init secret
di hape saya sudah sama dengan yang di tabel users MySQL.
Kini user sudah siap mencoba untuk login ke aplikasi MyTestBank di URL
https://localhost/mytestbank/login.php . Berikut ini adalah screen
capture ketika user login.
Setelah login berhasil, kemudian user dihadapkan pada form untuk
melakukan transfer uang. Berikut ini adalah screen shot pada browser dan
hp user ketika user melakukan transfer.
Setelah memasukkan OTP dengan benar, server memberikan informasi
“Transfer Success”. Kini user telah berhasil melakukan transfer. Berikut
adalah screenshot ketika transfer berhasil dilakukan.
0 Comments
Bagaimana Pendapat Anda ?