Amri Shodiq
www.ubuntulinux.or.id
amri.shodiq@gmail.com

Abstraksi
Artikel saya ini bermaksud untuk mengajak para web programmer untuk kembali meninjau metode otentikasi login yang mereka tawarkan. Apakah sudah cukup aman untuk disebut sebagai otentikasi atau belum. Saya melihat adanya mekanisme yang cukup umum digunakan sebagai metode otentikasi login pada banyak website dan Content Management System.

Saya tidak bermaksud menyerang para web programmer (terutama pengguna PHP) dengan menyatakan bahwa beberapa login.php adalah omong kosong. Tentu saja saya memiliki dasar mengapa saya mengatakannya demikian.


Mekanisme yang umum digunakan oleh para web programmer untuk suatu mekanisme login adalah (kurang lebih) sebagai berikut:

  1. ditampilkan halaman web yang menampilkan bahwa user perlu memasukkan username dan password
  2. user akan memasukkan username dan password kemudian mengklik tombol submit, biasanya bertuliskan Login atau OK
  3. kedua variabel yang diisikan oleh user akan diteruskan ke server
  4. sesampainya di server, suatu mekanisme pencocokan berlangsung, mekanisme tersebut adalah script (PHP atau ASP, dll) di server akan mengambil nilai MD5 dari password kemudian mencocokkannya dengan nilai MD5 password yang tersimpan di database server
  5. jika MD5 password dari user cocok dengan MD5 password yang tersimpan dalam database, maka akan diberikan cookie atau session
  6. setelah memiliki cookie atau session, maka user dapat melakukan hal-hal khusus seperti mengirimkan artikel

Ilustrasinya sebagai berikut (tidak spesifik nilai MD5-nya) :

           Client         

       $Username='amri'
      $Password='rahasia'
               |
               |
               |
               *
   login.php?username=amri&password=rahasia
               |
               |
               |
               *

             Server
   MD5($password) >< \"45677AC09901120D9EF\"  

               |
               |
               |
               *
            Database
   id: 00981
   username: amri
   password: 45677AC09901120D9EF

Sepintas nampaknya, mekanisme ini sudah cukup aman karena menggunakan algoritma kriptografi yaitu MD5. Tetapi sebenarnya apakah yang diamankan? Satu-satunya yang diamankan adalah password user yang tersimpan di dalam database, karena disimpan dalam bentuk nilai hash-nya! Lalu bagaimana dengan

  • variabel yang dikirim dari sisi user (di komputer klien, misalnya di warnet atau kantor yang tentu saja memiliki administrator yang dapat melihat traffic jaringan)?
  • mekanisme MD5 yang terjadi di server, apakah cukup memberi keamanan?
  • password pada sisi server, mengapa perlu disimpan dalam bentuk nilai hash-nya (MD5)?

Mari kita bahas poin-poin tersebut satu persatu.

Keamanan variabel selama pengiriman dari sisi klien ke server

Variabel username dan password yang diberikan oleh user pada mekanisme login langkah 1 akan dikirim dari browser klien, melalui jaringan, melewati ISP-ISP hingga akhirnya tiba di server hosting. Jika protokol yang digunakan adalah https maka, anda dapat merasa cukup lega karena variabel-variabel akan dikirim setelah terlebih dahulu dienkripsi dengan SSL yang didukung oleh browser. Tetapi, tidak semua server web hosting memberikan layanan untuk protokol ini. Protokol yang umum digunakan adalah http, dan dengan keterbatasan ini kita akan bekerja.

Protokol http adalah protokol plain, yang berarti semua data dikirimkan tanpa proses enkripsi. Semua pengamanan dipercayakan sebagian kepada web programmer dan sisanya kepada user. Jadi apabila ditanyakan bagaimana tingkat keamanan login dengan protokol ini (tanpa mekanisme kriptografi), maka jawabnya adalah 0%. Dengan kondisi demikian, data-data yang bersifat rahasia adalah tanggung jawab kedua pihak tersebut.

Dengan keadaan di atas, dapat diartikan bahwa web programmer harus memberikan perhatian lebih kepada pengamanan data, termasuk data otentikasi. Password adalah informasi yang krusial bagi seorang user, apalagi pada web-web yang bersifat komersial. Tanpa kriptografi, password yang dikirimkan oleh user dapat dengan mudah diambil dengan tools packet sniffer oleh pendekar-pendekar berwatak jahat, terutama di titik-titik strategis di sepanjang jaringan internet yang dilewati. Dalam hal ini kita perlu selalu waspada, dalam hal ini dapat diartikan sebagai selalu curiga kepada siapa saja baik administrator jaringan tempat kita bekerja, administrator di tempat ISP kita berlangganan, dan ISP-ISP yang mungkin kita tidak kenal tetapi data kita melaluinya. Karena kita menggunakan TCP/IP, ini hampir berarti semua orang.

Dengan demikian, perlu kriptografi untuk mengamankan mekanisme login kita. Beberapa web mewujudkannya dalam bentuk JavaScript yang digunakan untuk mengolah variabel username dan password tepat setelah tombol Submit diklik sebelum variabel tersebut dikirim. Contoh web site yang menggunakan mekanisme ini adalah Yahoo Mail. Salut kepada Yahoo Mail. Namun, trik pengamanan tidak terbatas menggunakan JavaScript saja. Yang penting adalah pengamanan tersebut harus berjalan sebelum variabel dikirimkan (client side). Caranya dapat menggunakan JavaScript, VbScript, ActionScript/Flash atau Applet Java.

Mengapa password yang tersimpan dalam database berbentuk nilai hash-nya (MD5)?

Sebenarnya langkah ini ditujukan untuk mengamankan password di sisi server. Mekanisme ini melindungi password-password tersebut dari administrator server web hosting kita dan orang lain yang memiliki akses ke server tersebut, misalnya hacker.

Mengapa MD5?

Sebenarnya kita dapat menggunakan algoritma hash yang lain, misalnya SHA-1. Yang penting adalah penggunaan algoritma hash, bukan enkripsi. Mengapa demikian? fungsi hash adalah bagian dari fungsi yang tidak dapat dikembalikan ke nilai asalnya. Dengan demikian jika kita mengetahui nilai hash dari suatu string, kita tidak dapat mendapatkan kembali nilai string tersebut. Karena yang kita bicarakan adalah password, maka tidak ada masalah karena mekanisme login hanya perlu untuk mencocokkan apakah password yang dikirimkan oleh user ‘cocok’ dengan nilai asli password nilai hash-nya tersimpan di dalam database. Hal ini terpecahkan karena input string yang sama akan memiliki nilai hash yang sama. Jadi nilai password aslinya hampir-hampir tidak diperlukan lagi. Satu-satunya kasus yang memerlukannya adalah ketika user lupa passwordnya dan menginginkan passwordnya kembali, dan ini di luar konteks artikel ini.

Bagaimana dengan enkripsi? Berbeda dengan algoritma hash, algoritma enkripsi bisa mengembalikan nilai asli string, asal diberikan kunci/key yang sesuai. Jadi apabila kita mengenkrip suatu string dengan DES atau Blowfish dengan kunci ‘A’, kita dapat mendekrip kembali string tersebut dengan kunci ‘A’. Kunci yang digunakan untuk mendekrip bisa sama dengan kunci pada proses enkripsi (metode enkripsi simetrik) atau berbeda (metode enkripsi asimetrik/public key). Jadi, apabila web programmer berniat mengamankan password dalam database dengan enkripsi, dia perlu berhati-hati karena nilai password tersebut bisa dikembalikan/didekrip, baik secara legal maupun attack.

Solusi alternatif

             Client         

    $Username='amri'
    $Password='rahasia'

               |
               |
               |
               *
    login.php?request=$Request
               |
               |
               |
               *
           Server

    dekrip($Request) ->$Username.\" \".$Password
    MD5($Password) >< \"45677AC09901120D9EF\"
               |
               |
               |
               *
    $Request=enkrip($Username.\" \".$Password)
               |
               |
               |
               *
           Database
   id: 00981
   username: amri
   password: 45677AC09901120D9EF

Dengan mekanisme di atas, password selama pengiriman aman, password di server aman, semua senang. Yang menjadi pertanyaan sekarang adalah, karena enkripsi membutuhkan kunci, bagaimana distribusi kuncinya? Tak ada pemecahan lain selain memberitahukan kunci tersebut kepada user. Masalahnya, jika kita memberitahukan kunci kepada user, apakah user tersebut dapat dipercaya untuk tidak membocorkan kunci tersebut? Apakah kunci harus selalu berganti setiap kali pengiriman? Bagaimana kita yakin bahwa client dan server menggunakan kunci yang cocok.

Metode enkripsi asimetrik menjawab pertanyaan di atas dengan sangat baik. Karena dengan metode ini kunci enkripsi dan dekripsi berbeda, maka kita tidak perlu takut kunci akan bocor. Public key memang untuk didistribusikan secara publik. Kunci tidak perlu berganti-ganti karena kunci dengan panjang tertentu (misalnya 1024-bit) masih cukup kuat untuk jangka waktu yang cukup lama. Memang ada keterbatasan panjang plain text yang dapat dienkripsi, tetapi karena dalam hal ini yang dienkripsi hanya username dan password, maka ini belum menjadi masalah.

   enkripsi($Username.\" \".$Password, $publicKey)
                       |
                       |
                       |
                       *

                    internet 

                       |
                       |
                       |
                       *

     dekripsi($ciphertext, $privateKey)

                       |
                       |
                       |
                       *
                +-------------+
                |             |
                |  $Username  |
                |  $Password  |
                |             |
                +-------------+
Iklan