Salt
Penggunaan hash untuk menyimpan password merupakan cara yang standar di berbagai aplikasi. Cara ini sederhana, tapi hash saja memiliki kelemahan:
- jika ada dua atau lebih orang passwordnya sama, maka akan terlihat bahwa hashnya sama.
- bisa dilakukan dictionary attack. Artinya: hash semua kata di kamus sekali, lalu cocokkan hashnya
Cara yang lebih baik adalah dengan menambahkan salt, berupa beberapa karakter random yang berbeda untuk tiap entry. Jadi misalnya jika password untuk user1 adalah 123, kita bisa menghasilkan salt random misalnya “xcd”, lalu salt ini dihash bersama password hash(“xcd”+”123”). Jika hash yang dipakai adalah MD5, maka hasilnya:
4c88e409f0d1938d4f0adf7bdc896fbe
Di dalam database atau file, kita perlu menyimpan salt yang dipakai: “xcd”, misalnya seperti ini: xcd$4c88e409f0d1938d4f0adf7bdc896fbe
Jika ada user2 yang memakai password yang sama “123”, maka kemungkinan akan mendapatkan salt yang berbeda, misalnya “cx2” yang jika dihash menjadi:
262f5f51da3e4a320f745d0cafe54a3e
Ini jauh berbeda dari hash user1 yang sama-sama memakai password 123.
Hash untuk proteksi request/response
Banyak sistem yang berkomunikasi dengan sistem lain memakai hash dengan “secret” (string rahasia) yang diketahui kedua belah pihak. Prinsip kerjanya begini: data ditambah dengan secret lalu dihash. Hash ini dipakai sebagai message authentication code (MAC).
Misalnya kita punya string request: amount=2&price=10000 (asumsi bahwa nama field terurut abjad menaik). Lalu kita memiliki key “RAHASIA”, maka kita bisa membuat hash dengan MD5(“RAHASIAamount=2&price=10000”) dan hasilnya adalah: 0bb770c5349c2fe268f47a767a6ccc8e
String ini kemudian dikirimkan ke pihak lain seperti ini:
amount=2&price=10000&hash=0bb770c5349c2fe268f47a767a6ccc8e
Pihak lain juga mengetahui kata RAHASIA tersebut sehingga bisa memverifikasi agar datanya bisa tetap tidak diubah.
Penggunaan konstruksi hash(SECRET+message) ini memiliki kelemahan yaitu adanya kemungkinan hash length extension attack. Penjelasan lebih lanjut mengenai ini bisa dibaca di wikipedia. Konstruksi hash(message+SECRET) sedikit lebih aman, tapi juga tidak terlalu aman dari yang namanya preimage attack.
HMAC
HMAC atau hash based Message Authentication Code merupakan bentuk autentikasi dengan menggunakan Hash dengan cara tertentu (tidak sekedar secret+message atau message+secret).
Definisi HMAC dari RFC 2104 adalah seperti ini:
Fungsi H adalah sebuah fungsi hash (misalnya SHA1, MD5 atau yang lain). K’ didefinisikan sebagai hasil H(KEY), sementara ipad dan opad hanyalah byte-byte padding (supaya ukurannya bloknya sama jika kurang dari panjang tertentu). Di RFC 2104 nilai opad adalah 0x5c dan ipad adalah 0x36. Operasi || artinya penggabungan (concatenation).
Jadi sebenarnya fungsi HMAC hanya memakai fungsi Hash biasa yang dilakukan 2 kali, plus padding di kasus tertentu. Konstruksi hmac ini lebih aman dibandingkan Hash(SECRET+data) atau hash(data+SECRET).
Tapi tetap perlu diperhatikan faktor data yang akan dihash seperti temuan saya pada bug mastercard. Meskipun HMAC sudah dipakai, tapi karena kesalahan pada representasi data, maka cara ini bisa memiliki kelemahan.
Penutup
Banyak pemula yang masih bingung dan belum memahami fungsi hash. Banyak juga yang mencampuradukkan antara hash dengan enkripsi. Karena konstruksi MAC (message authentication code) yang memakai SECRET, dikira ini adalah key untuk enkripsi. Hash sifatnya searah, sedangkan enkripsi sifatnya dua arah (jika diketahui kuncinya maka hasil enkripsi bisa dikembalikan menjadi data semula).