Menu

PHP password_hash() ve password_verify(): Parola Saklama

Bir parolayı password_hash($password, PASSWORD_DEFAULT) ile hash'leyin, 60 karakterlik sonucu saklayın ve bir girişi password_verify($password, $hash) ile kontrol edin. Hash'in neden her seferinde değiştiğini, maliyeti, password_needs_rehash, Argon2id ve md5 ile sha1'in parolalar için neden yanlış olduğunu öğrenin.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

Parolaları password_hash($password, PASSWORD_DEFAULT) ile saklayın ve bir girişi true veya false döndüren password_verify($password, $hash) ile kontrol edin. Parolanın kendisini asla saklamayın ve bunun için asla md5() veya sha1() kullanmayın.

İki kez çalıştırın: hash her seferinde farklıdır ve iki sürüm de doğrulanır. Aynısı bu sayfadaki her hash için geçerlidir, bu yüzden çıktınız başka kimseninkiyle eşleşmez.

password_verify ile giriş yapma

Bir giriş, gönderilen parolayı hesap oluşturulurken kaydedilen hash'e karşı kontrol eder. Bu blok bir kullanıcıyı "kaydeder" ve ardından bir giriş formu gösterir; doğru parolayı (hunter2), sonra yanlış birini deneyin.

Hata mesajı bilinmeyen bir e-posta ve yanlış bir parola için aynıdır. Hangisinin yanlış olduğunu söylemek bir saldırgana hangi e-postaların hesabı olduğunu söyler. Başarılı bir girişten sonra gerçek bir site, oturumlar sayfasında gösterildiği gibi kullanıcı id'sini oturumda saklar.

Hash'in içinde ne var

Bir bcrypt hash'i password_verify() fonksiyonunun ihtiyaç duyduğu her şeyi tutan tek bir dizgedir: algoritma, maliyet ve tuz, ardından hash'in kendisi. password_get_info() ilk kısımları geri okur.

Tuz hash'te saklandığı için yalnızca bir veritabanı sütununa ihtiyacınız olur ve aynı parolaya sahip iki kullanıcı yine farklı hash'ler alır. O sütunu VARCHAR(255) yapın: bcrypt 60 karakterdir, ama PASSWORD_DEFAULT daha uzun çıktılı bir algoritmaya geçebilir.

Maliyeti seçme

Maliyet, her hash'in bilerek ne kadar yavaş olduğudur ve her adım işi ikiye katlar. PHP 8.3 bcrypt için 10 maliyetini kullanır (PHP 8.4 varsayılanı 12 değerine yükseltti). Bir giriş kabaca 100 ile 300 ms hash'leme sürmelidir; bunu kendi sunucunuzda ölçün:

Sayılar makineye bağlıdır, ama her satır bir öncekinin yaklaşık iki katı olmalıdır. Daha yüksek değer kırmaya karşı daha güvenli, her giriş için daha yavaştır, bu yüzden giriş sayfanızın kaldırabileceği en yüksek maliyeti seçin.

password_needs_rehash ile eski hash'leri yükseltme

Maliyeti yükselttiğinizde ya da PHP PASSWORD_DEFAULT değerini değiştirdiğinde var olan hash'ler çalışmaya devam eder ve password_needs_rehash() hangilerinin eskidiğini söyler. Düz parolanın elinizde olduğu tek an giriştir, bu yüzden yükseltmeyi orada yaparsınız:

$2y$10$ öneki $2y$12$ olur ve bir sonraki girişte password_needs_rehash() false döndürür.

Parolalar için asla md5 veya sha1 kullanmayın

md5() ve sha1() tuzsuz, hızlı genel amaçlı hash'lerdir. Hızlı olmak parolalar için tam olarak yanlıştır: sızdırılmış bir tabloya sahip bir saldırgan bir GPU ile saniyede milyarlarca tahmin deneyebilir ve yaygın bir parolanın tuzsuz hash'i zaten herkese açık arama tablolarındadır. Hızı karşılaştırın:

password_hash() bir hash ürettiği sürede md5 yüz binlerce hash üretir, yani bir kırıcının her tahmini o kadar kat daha ucuzdur. 5f4dcc3b5aa765d61d8327deb882cf99 için arama yapın, "password" kelimesini hemen bulursunuz.

md5 hash'lerinden oluşan bir tabloyu devralırsanız onları doğrudan dönüştüremezsiniz. Bunun yerine sarın: password_hash($oldMd5) saklayın ve password_verify(md5($input), $stored) ile doğrulayın, sonra o kullanıcı bir sonraki girişini yaptığında her birini normal bir hash ile değiştirin.

Argon2id ve 72 bayt sınırı

PASSWORD_ARGON2ID hash başına daha fazla bellek kullanır, bu da GPU ile kırmayı çok daha pahalı yapar. PHP libargon2 ile derlendiğinde kullanılabilir (çoğu Linux paketi öyledir); defined('PASSWORD_ARGON2ID') ile kontrol edin.

Son satır bool(true) yazdırır: iki farklı parola eşleşir, çünkü bcrypt 72. bayttan sonraki her şeyi yok sayar. Gerçek parolalar buna nadiren ulaşır, ama Japonca veya diğer çok baytlı yazılardaki parola cümleleri yaklaşık 24 karakterde 72 bayta ulaşır. Çok uzun parolalara izin veriyorsanız böyle bir sınırı olmayan Argon2id kullanın. password_verify() iki algoritmayla da çalışır, bu yüzden yukarıdaki gibi password_needs_rehash() ile geçiş yapabilirsiniz.

Sıkça Sorulan Sorular

password_hash neden her seferinde farklı bir sonuç veriyor?

Her çağrı yeni bir rastgele tuz (salt) üretir ve onu hash'in içinde saklar, bu yüzden aynı parola her seferinde farklı bir dizge verir. Bu bilinçlidir: password_verify() tuzu saklanan hash'ten geri okur, bu yüzden doğru parola için yine true döndürür.

password_hash için parola sütunu ne uzunlukta olmalı?

PASSWORD_DEFAULT ile üretilen bir bcrypt hash'i bugün 60 karakterdir, ama varsayılan algoritma gelecekteki bir PHP sürümünde değişebilir. Daha uzun bir hash geçiş gerektirmeden sığsın diye VARCHAR(255) kullanın.

password_verify neden hep false döndürüyor?

Olağan nedenler kesilmiş bir hash (bir VARCHAR(50) sütunu 60 karakterlik hash'i keser), ikinci argüman olarak sakladığınız hash yerine bir şeyin yeni bir password_hash() sonucunu vermek, md5() ile yapılmış bir hash'e karşı karşılaştırmak ya da saklanan değerdeki fazladan boşluklardır. strlen($hash) değerinin 60 olduğunu kontrol edin ve düz parolayı ilk argüman olarak verin.

PHP'de bir password_hash değerinin şifresini çözebilir miyim?

Hayır. Bir hash tek yönlüdür: onu parolaya geri çeviren bir fonksiyon yoktur. Bir parolayı kontrol etmek için denemeyi hash'ler ve karşılaştırırsınız, password_verify() bunu yapar. Unutulan bir parola için eski parola yerine bir sıfırlama bağlantısı gönderin.

PASSWORD_DEFAULT, PASSWORD_BCRYPT veya PASSWORD_ARGON2ID mi kullanmalıyım?

PASSWORD_DEFAULT olağan seçimdir: bugün bcrypt'tir ve PHP onu daha sonra daha güçlü bir algoritmaya taşıyabilir; password_needs_rehash() buna kademeli olarak geçmenizi sağlar. PASSWORD_ARGON2ID GPU ile kırmaya karşı daha güçlüdür ve PHP derlemeniz onu içeriyorsa kullanmak sorun değildir.

Coddy programlama dilleri çizimi

Coddy ile kodlamayı öğren

BAŞLA