Penggunaan fungsi HASH.

Dari waktu ke waktu, server dan database dicuri atau disusupi. Mengingat hal ini, penting untuk memastikan bahwa beberapa data penting pengguna, seperti kata sandi, tidak dapat dipulihkan. Hari ini, kita akan mempelajari dasar-dasar di balik hashing dan apa yang diperlukan untuk melindungi kata sandi di aplikasi web Anda

Tutorial yang diterbitkan ulang

Setiap beberapa minggu, kami mengunjungi kembali beberapa posting favorit pembaca kami dari seluruh sejarah situs ini. Tutorial ini pertama kali diterbitkan pada Januari 2011


1. Penolakan

Kriptologi adalah subjek yang cukup rumit, dan saya sama sekali bukan ahlinya. Ada penelitian yang sedang berlangsung di bidang ini, di banyak universitas dan badan keamanan

Pada artikel ini, saya akan mencoba untuk menjaga hal-hal sesederhana mungkin, sambil menyajikan kepada Anda metode penyimpanan kata sandi yang cukup aman di aplikasi web.


2. Apa yang Dilakukan "Hashing"?

Hashing mengubah sepotong data (kecil atau besar), menjadi potongan data yang relatif pendek seperti string atau bilangan bulat

Ini dilakukan dengan menggunakan fungsi hash satu arah. "Satu arah" berarti sangat sulit (atau hampir tidak mungkin) untuk membalikkannya

Contoh umum dari fungsi hash adalah md5(), yang cukup populer di berbagai bahasa dan sistem

$data = "Hello World";
$hash = md5($data);
echo $hash; // b10a8db164e0754105b7a99be72e3fe5

Dengan

echo crc32('supersecretpassword');
// outputs: 323322056
_5, hasilnya akan selalu berupa string berisi 32 karakter. Tapi, itu hanya berisi karakter heksadesimal; . Anda mungkin
echo crc32('supersecretpassword');
// outputs: 323322056
5 string dan bahkan data yang lebih panjang, dan Anda masih akan mendapatkan hash selama ini. Fakta ini saja dapat menunjukkan mengapa ini dianggap sebagai fungsi "satu arah".


3. Menggunakan Fungsi Hash untuk Menyimpan Kata Sandi

Prosesnya biasanya saat pendaftaran pengguna

  • Pengguna mengisi formulir pendaftaran, termasuk bidang kata sandi
  • Skrip web menyimpan semua informasi ke dalam database
  • Namun, kata sandi dijalankan melalui fungsi hash, sebelum disimpan
  • Versi asli kata sandi belum disimpan di mana pun, jadi secara teknis akan dibuang

Dan proses login

  • Pengguna memasukkan nama pengguna (atau email) dan kata sandi
  • Skrip menjalankan kata sandi melalui fungsi hashing yang sama
  • Skrip menemukan catatan pengguna dari database, dan membaca hash kata sandi yang disimpan
  • Kedua nilai ini dibandingkan, dan akses diberikan jika cocok

Setelah kami memutuskan metode yang sesuai untuk memasukkan kata sandi, kami akan menerapkan proses ini nanti di artikel ini

Perhatikan bahwa kata sandi asli tidak pernah disimpan di mana pun. Jika database dicuri, login pengguna tidak dapat dikompromikan, bukan? . " Mari kita lihat beberapa masalah potensial


4. Masalah #1. Tabrakan hash

"Tabrakan" hash terjadi ketika dua input data yang berbeda menghasilkan hash yang sama. Kemungkinan terjadinya hal ini bergantung pada fungsi yang Anda gunakan

Bagaimana ini bisa dieksploitasi?

Misalnya, saya telah melihat beberapa skrip lama yang menggunakan crc32() untuk meng-hash kata sandi. Fungsi ini menghasilkan integer 32-bit sebagai hasilnya. Ini berarti hanya ada 2^32 (yaitu 4. 294. 967. 296) kemungkinan hasil

Mari hash kata sandi

echo crc32('supersecretpassword');
// outputs: 323322056
_

Sekarang, mari kita asumsikan peran seseorang yang telah mencuri database, dan memiliki nilai hash. Kami mungkin tidak dapat mengonversi 323322056 menjadi 'supersecretpassword', tetapi kami dapat menemukan kata kunci lain yang akan dikonversi ke nilai hash yang sama, dengan skrip sederhana

set_time_limit(0);
$i = 0;
while (true) {

  if (crc32(base64_encode($i)) == 323322056) {
		echo base64_encode($i);
		exit;
	}

	$i++;
}
_

Ini mungkin berjalan untuk sementara waktu, meskipun, pada akhirnya, itu akan mengembalikan sebuah string. Kita dapat menggunakan string yang dikembalikan ini -- alih-alih 'supersecretpassword' -- dan ini akan memungkinkan kita untuk berhasil masuk ke akun orang tersebut

Misalnya, setelah menjalankan skrip persis ini selama beberapa detik di komputer saya, saya mendapatkan '

echo crc32('supersecretpassword');
// outputs: 323322056
7'. Mari kita mengujinya

echo crc32('supersecretpassword');
// outputs: 323322056

echo crc32('MTIxMjY5MTAwNg==');
// outputs: 323322056
_

Bagaimana ini bisa dicegah?

Saat ini, PC rumahan yang kuat dapat digunakan untuk menjalankan fungsi hash hampir satu miliar kali per detik. Sehingga diperlukan sebuah fungsi hash yang memiliki range yang sangat besar

Misalnya,

echo crc32('supersecretpassword');
// outputs: 323322056
_5 mungkin cocok, karena menghasilkan hash 128-bit. Artinya 340. 282. 366. 920. 938. 463. 463. 374. 607. 431. 768. 211. 456 kemungkinan hasil. Tidak mungkin melalui banyak iterasi untuk menemukan tabrakan. Namun beberapa orang masih menemukan cara untuk melakukan ini (lihat di sini)

Sha1

Sha1() adalah alternatif yang lebih baik, dan menghasilkan nilai hash 160-bit yang lebih panjang


5. Masalah #2. Meja Pelangi

Bahkan jika kita memperbaiki masalah tabrakan, kita tetap tidak aman

Tabel pelangi dibuat dengan menghitung nilai hash dari kata-kata yang umum digunakan dan kombinasinya

Tabel ini bisa memiliki jutaan atau bahkan milyaran baris

Misalnya, Anda dapat membaca kamus, dan menghasilkan nilai hash untuk setiap kata. Anda juga dapat mulai menggabungkan kata-kata, dan menghasilkan hash untuk kata-kata tersebut. Bukan itu saja;

Mempertimbangkan betapa murahnya penyimpanan saat ini, Meja Pelangi raksasa dapat diproduksi dan digunakan

Bagaimana ini bisa dieksploitasi?

Bayangkan database besar dicuri, bersama dengan 10 juta hash kata sandi. Cukup mudah untuk menemukan meja pelangi untuk masing-masing. Tidak semuanya akan ditemukan, tentu saja, tapi tetap saja. beberapa dari mereka akan ditemukan

Bagaimana ini bisa dicegah?

Kita bisa mencoba menambahkan "garam". Ini sebuah contoh

$password = "easypassword";

// this may be found in a rainbow table
// because the password contains 2 common words
echo sha1($password); // 6c94d3b42518febd4ad747801d50a8972022f956

// use bunch of random characters, and it can be longer than this
$salt = "f#@V)Hu^%Hgfds";

// this will NOT be found in any pre-built rainbow table
echo sha1($salt . $password); // cd56a16759623378628c0d9336af69b74d9d71a5
_

Apa yang pada dasarnya kami lakukan adalah menggabungkan string "garam" dengan kata sandi sebelum melakukan hashing. String yang dihasilkan jelas tidak akan ada di tabel pelangi yang dibuat sebelumnya. Tapi, kita belum aman


6. Masalah #3. Meja Pelangi (selengkapnya)

Ingatlah bahwa Tabel Pelangi dapat dibuat dari awal, setelah database dicuri

Bagaimana ini bisa dieksploitasi?

Bahkan jika garam digunakan, itu mungkin telah dicuri bersama dengan basis datanya. Yang harus mereka lakukan hanyalah membuat Tabel Pelangi baru dari awal, tetapi kali ini mereka menambahkan garam ke setiap kata yang mereka masukkan ke dalam tabel.

Misalnya, dalam Tabel Pelangi generik, "

echo crc32('supersecretpassword');
// outputs: 323322056
_9" mungkin ada di sana. Tapi di Rainbow Table baru ini, mereka juga punya "
set_time_limit(0);
$i = 0;
while (true) {

  if (crc32(base64_encode($i)) == 323322056) {
		echo base64_encode($i);
		exit;
	}

	$i++;
}
0". Ketika mereka menjalankan semua 10 juta hash asin yang dicuri di atas meja ini, mereka akan kembali dapat menemukan beberapa kecocokan

Bagaimana ini bisa dicegah?

Sebagai gantinya, kita dapat menggunakan "garam unik", yang berubah untuk setiap pengguna

Kandidat untuk jenis garam ini adalah nilai id pengguna dari database

$hash = sha1($user_id . $password);

Ini mengasumsikan bahwa nomor id pengguna tidak pernah berubah, yang biasanya terjadi

Kami juga dapat membuat string acak untuk setiap pengguna dan menggunakannya sebagai garam unik. Tetapi kita perlu memastikan bahwa kita menyimpannya di catatan pengguna di suatu tempat

// generates a 22 character long random string
function unique_salt() {

	return substr(sha1(mt_rand()),0,22);
}

$unique_salt = unique_salt();

$hash = sha1($unique_salt . $password);

// and save the $unique_salt with the user record
// ...

Metode ini melindungi kita dari Tabel Pelangi, karena sekarang setiap kata sandi telah diasinkan dengan nilai yang berbeda. Penyerang harus menghasilkan 10 juta Tabel Pelangi terpisah, yang sama sekali tidak praktis


7. Masalah #4. Kecepatan Hash

Sebagian besar fungsi hash telah dirancang dengan mempertimbangkan kecepatan, karena sering digunakan untuk menghitung nilai checksum untuk kumpulan data dan file besar, untuk memeriksa integritas data

Bagaimana ini bisa dieksploitasi?

Seperti yang saya sebutkan sebelumnya, PC modern dengan kartu GPU yang kuat (ya, kartu video) dapat diprogram untuk menghitung sekitar satu miliar hash per detik. Dengan cara ini, mereka dapat menggunakan serangan brute force untuk mencoba setiap kemungkinan kata sandi

Anda mungkin berpikir bahwa membutuhkan panjang kata sandi minimal 8 karakter mungkin akan membuatnya aman dari serangan brute force, tetapi mari kita tentukan apakah itu benar-benar masalahnya

  • Jika kata sandi dapat berisi huruf kecil, huruf besar, dan angka, yaitu 62 (26+26+10) karakter yang memungkinkan
  • String sepanjang 8 karakter memiliki 62^8 kemungkinan versi. Itu sedikit di atas 218 triliun
  • Dengan kecepatan 1 miliar hash per detik, itu dapat dipatahkan dalam waktu sekitar 60 jam

Dan untuk kata sandi sepanjang 6 karakter, yang juga cukup umum, akan memakan waktu kurang dari 1 menit

Jangan ragu untuk meminta kata sandi 9 atau 10 karakter, tetapi Anda mungkin mulai mengganggu beberapa pengguna Anda

Bagaimana ini bisa dicegah?

Gunakan fungsi hash yang lebih lambat

Bayangkan Anda menggunakan fungsi hash yang hanya dapat berjalan 1 juta kali per detik pada perangkat keras yang sama, bukan 1 miliar kali per detik. Ini kemudian akan membutuhkan penyerang 1000 kali lebih lama untuk memaksa hash secara kasar. 60 jam akan berubah menjadi hampir 7 tahun

Salah satu cara untuk melakukannya adalah dengan menerapkannya sendiri

function myhash($password, $unique_salt) {

	$salt = "f#@V)Hu^%Hgfds";
	$hash = sha1($unique_salt . $password);

	// make it take 1000 times longer
	for ($i = 0; $i < 1000; $i++) {
		$hash = sha1($hash);
	}

	return $hash;
}

Atau Anda dapat menggunakan algoritme yang mendukung "parameter biaya", seperti BLOWFISH. Di PHP, ini bisa dilakukan dengan menggunakan fungsi

set_time_limit(0);
$i = 0;
while (true) {

  if (crc32(base64_encode($i)) == 323322056) {
		echo base64_encode($i);
		exit;
	}

	$i++;
}
1

function myhash($password, $unique_salt) {

	// the salt for blowfish should be 22 characters long

	return crypt($password, '$2a$10$'.$unique_salt);

}

Parameter kedua dari fungsi

set_time_limit(0);
$i = 0;
while (true) {

  if (crc32(base64_encode($i)) == 323322056) {
		echo base64_encode($i);
		exit;
	}

	$i++;
}
1 berisi beberapa nilai yang dipisahkan oleh tanda dolar ($)

Nilai pertama adalah '$2a', yang menunjukkan bahwa kita akan menggunakan algoritma BLOWFISH

Nilai kedua, dalam hal ini '$10', adalah "parameter biaya". Ini adalah logaritma basis-2 dari berapa banyak iterasi yang akan dijalankan (10 => 2^10 = 1024 iterasi. ) Jumlah ini dapat berkisar antara 04 dan 31

Mari kita jalankan sebuah contoh

function myhash($password, $unique_salt) {
	return crypt($password, '$2a$10$'.$unique_salt);

}
function unique_salt() {
	return substr(sha1(mt_rand()),0,22);
}


$password = "verysecret";

echo myhash($password, unique_salt());
// result: $2a$10$dfda807d832b094184faeu1elwhtR2Xhtuvs3R9J1nfRGBCudCCzC

Hash yang dihasilkan berisi algoritma ($2a), parameter biaya ($10), dan 22 karakter garam yang digunakan. Sisanya adalah hash yang dihitung. Mari kita mengujinya

echo crc32('supersecretpassword');
// outputs: 323322056
_0

Saat kami menjalankan ini, kami melihat "Access Granted. "


8. Menyatukannya

Dengan mengingat semua hal di atas, mari kita menulis kelas utilitas berdasarkan apa yang telah kita pelajari sejauh ini

echo crc32('supersecretpassword');
// outputs: 323322056
_1

Berikut ini adalah penggunaan saat pendaftaran pengguna

echo crc32('supersecretpassword');
// outputs: 323322056
_2

Dan ini adalah penggunaan selama proses login user

echo crc32('supersecretpassword');
// outputs: 323322056
_3

9. Catatan tentang Ketersediaan Blowfish

Algoritme Blowfish mungkin tidak diterapkan di semua sistem, meskipun sekarang cukup populer. Anda dapat memeriksa sistem Anda dengan kode ini

echo crc32('supersecretpassword');
// outputs: 323322056
_4

Namun, pada PHP 5. 3, Anda tidak perlu khawatir;


Kesimpulan

Metode hashing kata sandi ini cukup solid untuk sebagian besar aplikasi web. Apa yang dia katakan, jangan lupa. Anda juga dapat meminta agar anggota Anda menggunakan kata sandi yang lebih kuat, dengan menerapkan panjang minimum, karakter campuran, angka & karakter khusus

Sebuah pertanyaan untuk Anda, pembaca. gimana cara hash passwordnya?

Apa gunanya fungsi hash?

Fungsi hash adalah setiap fungsi yang dapat digunakan untuk memetakan data dengan ukuran arbitrer ke nilai ukuran tetap . Nilai yang dikembalikan oleh fungsi hash disebut nilai hash, kode hash, intisari, atau hanya hash. Nilai biasanya digunakan untuk mengindeks tabel berukuran tetap yang disebut tabel hash.

Apa itu hash PHP?

Memperkenalkan Fungsi Password_hash di PHP . hash adalah sebuah mekanisme untuk memetakan suatu data yang diinputkan berupa text (Plain Text) menjadi output string (checksum) dengan kode acak yang memiliki panjang karakter yang tetap.

Apa fungsi hash di laravel?

Di sini hash digunakan untuk mengamankan password user pada aplikasi atau website yang kita buat . termasuk pada website atau aplikasi yang dibuat menggunakan Laravel.

Apa itu algoritma fungsi hash?

Algoritme hash, disebut juga algoritme intisari pesan digunakan untuk menghasilkan intisari pesan khusus untuk pesan acak . Algoritma hashing diklaim sebagai elemen penting dalam bidang kriptografi dan praktik keamanan.