password_hash Fonksiyonu
Aslında md5 fonksiyonu ve onunla şifre tuzlama
güncelliğini yitirmiş kabul edilir.
Bunu, ilerideki materyali anlamanız için
ve ayrıca başkalarının projeleriyle çalışırken
karşılaşabileceğiniz için öğrendik.
Tuzlanmış şifre elde etmek için daha gelişmiş
bir yöntem vardır. Bunun için password_hash
fonksiyonu kullanılır. İlk parametresi olarak
bir dizi alır, ikinci parametresi olarak da
şifreleme algoritması (ondan daha sonra bahsedeceğiz)
alır ve bu dizginin tuzuyla birlikte hash'ini döndürür.
Bu kodu birkaç kez çalıştırmayı deneyin:
<?php
echo password_hash('12345', PASSWORD_DEFAULT);
?>
Her seferinde farklı bir sonuç alacaksınız ve bu sonuçta dizginin ilk kısmı tuz, ikinci kısmı ise tuzlanmış şifre olacaktır.
Diyelim ki password_hash fonksiyonundan
elde edilmiş bir hash'imiz ve bir şifremiz var.
Bunun, bu şifrenin hash'i olup olmadığını
kontrol etmek için password_verify
fonksiyonu kullanılmalıdır. İlk parametre
olarak şifreyi, ikinci parametre olarak hash'i
alır ve true veya false döndürür.
Bir örnek üzerinden görelim:
<?php
$password = '12345'; // şifre
$hash = '$2y$10$xoYFX1mFPxBSyxaRe3iIRutxkIWhxGShzEhjYUVd3qpCUKfJE1k7a'; // hash
if (password_verify($password, $hash)) {
// bu şifrenin hash'i
} else {
// bu şifrenin hash'i değil
}
?>
Bu bize pratikte ne sağlar: Veritabanında tuzu saklamak için ayrı bir alan oluşturmamıza, bu tuzu oluşturmakla uğraşmamıza gerek yok - PHP hepsini bizim için halleder!
Yani, veritabanındaki password alanında
tuzlanmış şifreyi tuzuyla birlikte saklayacağız.
Bu durumda hash'lenmiş şifre daha uzun bir uzunluğa
sahip olacaktır. Bu nedenle veritabanında şifre
alanının boyutunu düzeltip 60 karakter
olarak ayarlamalıyız.
Şimdi kayıt kodunu düzeltelim. İşte şu anki hali:
<?php
function generateSalt()
{
$salt = '';
$saltLength = 8; // tuz uzunluğu
for($i = 0; $i < $saltLength; $i++) {
$salt .= chr(mt_rand(33, 126)); // ASCII-tablosundan karakter
}
return $salt;
}
$salt = generateSalt(); // tuz
$password = md5($salt . $_POST['password']); // şifreyi tuzlanmış hash'e dönüştür
?>
password_hash ile bunu şu şekilde kısaltacağız:
<?php
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
?>
Benzer şekilde giriş kodu da düzeltilecek:
<?php
$login = $_POST['login'];
$query = "SELECT * FROM users WHERE login='$login'"; // kullanıcıyı logine göre al
$res = mysqli_query($link, $query);
$user = mysqli_fetch_assoc($res);
if (!empty($user)) {
$hash = $user['password']; // Veritabanından tuzlanmış şifre
// Veritabanındaki hash'in girilen şifreyle eşleşip eşleşmediğini kontrol et
if (password_verify($_POST['password'], $hash)) {
// her şey tamam, giriş yap...
} else {
// şifre uygun değil, mesaj göster
}
} else {
// bu login ile kullanıcı yok, mesaj göster
}
?>
Giriş ve kayıt işlemlerinizi yeni öğrenilen fonksiyonlara uygun şekilde değiştirin.