bcrypt, Argon2 ve scrypt: 2026’da parola hash’leme
Kısa cevap: 2026’da başlayan herhangi bir yeni proje için Argon2id’yi m=19456, t=2, p=1 parametreleriyle kullanın. Bu, OWASP Password Storage Cheat Sheet temel önerisidir ve bugün üretime alabileceğiniz parola hash’leme algoritmaları arasında GPU ile yan kanal saldırılarına en güçlü direnci sunan algoritmadır.
Argon2’yi yığınınızda bulamazsanız (2026’da nadirdir, ancak bazı gömülü ya da eski çalışma zamanlarında olur), N=2^17, r=8, p=1 ile scrypt’e geçin. bcrypt’i yalnızca zaten bcrypt kullanan ve yeni bir bağımlılık ekleyemeyeceğiniz eski bir sisteme bağlıysanız cost=12 ile kullanın. FIPS-140 uyumluluğu zorunluysa PBKDF2-HMAC-SHA-256, 600.000 iterasyon ile devam edin.
| Algoritma | OWASP 2026 parametreleri | Ne zaman seçilir |
|---|---|---|
| Argon2id | m=19456 KiB, t=2, p=1 | Yeni projeler için varsayılan |
| scrypt | N=2^17, r=8, p=1 | Argon2 mevcut değilse |
| bcrypt | cost=12 (min 10) | Yalnızca eski sistemler |
| PBKDF2 | HMAC-SHA-256, 600k iterasyon | FIPS-140 gerektiğinde |
Yazının geri kalanı bu sayıların arkasındaki gerekçeyi, donanımınıza göre nasıl ayarlayacağınızı ve kullanıcılara parola sıfırlatmadan nasıl geçireceğinizi anlatıyor. Karşılaştırma için sağlam test parolaları üretmeniz gerekirse Rastgele Şifre Üretici’yi kullanın. Daha geniş bağlam için Web Güvenliği Temelleri rehberine bakın.
Parola hash’leme genel hash’lemeden niye farklıdır
Hash fonksiyonları dışarıdan hep aynı görünür: veri girer, sabit uzunlukta bir özet çıkar ve tersine çeviremezsiniz. Ama “şu 4 GB ISO’yu hash’le” ile “şu 12 karakterlik parolayı hash’le” işlerinin tasarım hedefleri tam olarak birbirinin tersidir. Birinin silikonun izin verdiği kadar hızlı olması gerekir. Diğerinin ise giriş gecikme bütçenizin tolere edebileceği kadar yavaş olması.
İkisini birbirine karıştırmak, sızıntıların hesap ele geçirmelere dönüşme şeklidir.
MD5 ve SHA-256 parolalar için niye yeterli değildir
MD5, SHA-1 ve SHA-256 gibi genel amaçlı hash’ler verim için tasarlandı. Sıradan CPU’larda saniyede gigabaytlarca, GPU’larda saniyede onlarca gigabayt veri işliyorlar. Bu da onları dosya sağlama toplamları ve içerik adresleme için ideal kılıyor; parolalar için ise felaket.
Tek bir RTX 4090 üzerinde Hashcat karşılaştırmaları, 2024’te kabaca MD5 için 164 GH/s ve SHA-256 için 22 GH/s gösteriyor. Sekiz karakterlik küçük harf-alfasayısal bir parola (36^8 ≈ 2,8 × 10^12 aday), MD5’e karşı tek bir GPU karşısında bir dakikadan kısa, SHA-256’ya karşı birkaç dakikadan kısa sürede düşer. sha256(password) saklayan, sızdırılmış bir veritabanı pratik olarak düz metindir.
Salt da sizi kurtarmaz. Salt, önceden hesaplanmış gökkuşağı tablolarının çalışmasını engeller, ancak hesap başına saldırıyı yavaşlatmak için bir şey yapmaz: saldırgan her adayı sızdırılmış salt ile birleştirip hash’ler.
Güvenlik dışı sağlama toplamları için MD5 ve SHA-256 hâlâ yararlıdır; MD5 ve SHA-256 Özet Üretici gibi araçlar tam olarak bunun için yapılmıştır. Her algoritmanın ne zaman uygun olduğuna dair derinlemesine bir karşılaştırma için MD5 vs SHA-256’yı okuyun. Parolalar için ise kasıtlı olarak yavaş bir hash gerekir.
Modern bir parola hash’inin üç özelliği
2026’da üretime alınmaya değer bir parola hash’i şu üç özelliğe sahiptir:
- Tasarım gereği yavaş, ayarlanabilir bir iş faktörü ile. Giriş 100–500 ms sürmelidir; kullanıcıların fark etmeyeceği kadar hızlı, çevrimdışı bir saldırganın milyon tahmin başına günlerini yakacağı kadar yavaş. Donanım geliştikçe değeri artırabilmeniz için iş faktörünün bir parametre olması gerekir.
- Kayıt başına salt. Parola başına benzersiz, rastgele bir salt gökkuşağı tablolarını boşa çıkarır ve saldırganı her hesaba ayrı ayrı saldırmaya zorlar. Modern algoritmalar bu salt’ı sizin için üretip çıktı dizesine gömer.
- Bellek-zor. GPU’lar ve ASIC’ler hesaplamada hızlıdır, ancak yüksek bant genişlikli bellekte pahalıdır. Hash başına onlarca MiB gerektiren bir algoritma, saldırganı paralelliğiyle orantılı RAM ayırmaya zorlar ve GPU çiftliklerinin maliyet etkinliğini bitirir.
bcrypt (1) ve (2)‘yi yakalar, ama (3)‘ü yakalayamaz. scrypt, üçünü birden vuran ilk algoritmaydı. Argon2 tasarımı rafine etti ve Password Hashing Competition’ı kazandı. Sonraki bölüm her birini sırayla açıklıyor.
Üç algoritma: mimari ve tradeoff’lar
bcrypt: Blowfish tabanlı, zaman-zor
bcrypt, 1999’da Niels Provos ve David Mazières tarafından OpenBSD için tasarlandı. Blowfish şifresi üzerine inşa edilmiştir; pahalı bir anahtar kurulum aşaması (“EksBlowfish”) 2^cost kez tekrarlanır. Tek ayarlanabilir parametre maliyet faktörüdür (“log rounds” da denir): her artış işi ikiye katlar. cost=10 hash’i 1.024 anahtar zamanlaması yapar; cost=14 ise 16.384.
bcrypt hash’i şöyle görünür:
$2b$12$R9h/cIPz0gi.URNNX3kh2OPST9/PgBkqquzi.Ss7KIUgO2t0jWMUW
│ │ │ │
│ │ │ └─ 31-char base64 hash
│ │ └─ 22-char base64 salt
│ └─ cost factor (12)
└─ algorithm identifier ($2b$ = bcrypt v2)
Format kendini açıklıyor: verify() saklanan dizeden cost ve salt’ı okur, ayrı bir sütun gerekmez.
Dezavantajlar gerçek. bcrypt’in bellek ayak izi yaklaşık 4 KiB’dır; üst seviye bir GPU’nun paralel olarak binlerce bcrypt çekirdeği çalıştırabileceği kadar küçük. Ve bcrypt, girdiyi 72 baytta sessizce kırpar. 100 karakterlik bir passphrase, ilk 72 baytı ile aynı güvenliğe sahiptir. Maksimum cost 31’dir, ancak ~16’nın üzerindeki herhangi bir değer sıradan donanımda giriş gecikmesini incitmeye başlar.
scrypt: bellek-zor öncüsü
scrypt, 2009’da Tarsnap yedekleme servisi için Colin Percival tarafından yayımlandı ve 2016’da RFC 7914 olarak standartlaştırıldı. Bellek-zorluk fikrini tanıttı: algoritma büyük bir tamponu sözde rastgele verilerle doldurur, ardından rastgele konumlardan okur ve herhangi bir uygulamayı belleği gerçekten ayırmaya zorlar.
scrypt üç parametre alır:
- N: CPU/bellek maliyeti (2’nin kuvveti olmalı)
- r: bayt cinsinden blok boyutu (bellek ve karıştırma turları için çarpan)
- p: paralellik (bağımsız hesaplamalar; çoğunlukla belleği ölçeklemeden CPU zamanını ölçeklemek için kullanılır)
Bellek kullanımı yaklaşık 128 × N × r bayttır. OWASP’ın önerdiği N=2^17, r=8 ile bu 128 × 131072 × 8 = 134.217.728 bayttır; tam olarak hash başına 128 MiB.
scrypt aynı zamanda bir anahtar türetme fonksiyonudur, yalnızca bir parola hash’i değil. Kripto para cüzdanlarında, tam disk şifrelemede ve orijinal Litecoin proof-of-work’te kullanılır. Bu çift rol, tek bir kütüphanede hem parola depolama hem de anahtar türetme gerektiğinde işe yarar.
Argon2 (id/i/d): Password Hashing Competition kazananı
Password Hashing Competition 2013’ten 2015’e kadar sürdü ve 24 aday algoritmayı bellek-zorluk, yan kanal direnci ve uygulama sadeliği açısından değerlendirdi. Argon2 kazandı. 2021’de RFC 9106 olarak standartlaştırıldı.
Argon2’nin üç çeşidi vardır. Farklar, karıştırma sırasında belleğin nasıl adreslendiğine iniyor:
- Argon2d veriye bağımlı bellek adresleri kullanır. Bu, GPU ve ASIC saldırılarına karşı direnci en üst düzeye çıkarır, ancak önbellek zamanlama yan kanalları üzerinden bilgi sızdırır. Kripto para proof-of-work için uygundur, kimlik doğrulama için değil.
- Argon2i veriden bağımsız adresler kullanır. Yan kanala karşı güvenli, ancak GPU tradeoff saldırılarına karşı biraz daha zayıf.
- Argon2id bir hibrittir: ilk geçişin ilk yarısı Argon2i indekslemesi (yan kanal güvenli), geri kalanı Argon2d indekslemesi (GPU dirençli) kullanır. RFC 9106 parola hash’leme için açıkça Argon2id’yi önerir, OWASP de öyle.
Argon2 üç parametre alır:
- m: KiB cinsinden bellek
- t: zaman maliyeti (bellek tamponu üzerinden geçiş sayısı)
- p: paralellik (eşzamanlı işlenen şerit sayısı)
Argon2id hash’i PHC dize formatını kullanır ve şöyle görünür:
$argon2id$v=19$m=19456,t=2,p=1$c29tZXNhbHQ$RdescudvJCsgt3ub+b+dWRWJTmaaJObG
bcrypt gibi tüm parametreler dizenin içine gömülmüştür, böylece verify() bir parametre tablosuna ihtiyaç duymaz.
OWASP 2026 önerilen parametreler
OWASP Password Storage Cheat Sheet kanonik referanstır. Aşağıdaki sayılar mevcut kılavuzuyla eşleşiyor. Tutucudurlar (100–500 ms giriş gecikme bütçesi olan tipik bir web sunucusu için boyutlandırılmıştır), yine de üretime almadan önce kendi donanımınızda karşılaştırma yapmalısınız.
Argon2id parametreleri: ilk tercih
OWASP’ın temel önerisi: m=19456 (19 MiB), t=2, p=1.
Sunucunuzda daha fazla RAM payı varsa, işi bellek ile zaman arasında kaydırabilirsiniz. RFC 9106 eşdeğer profiller yayımlar; OWASP bunlardan herhangi birini önerir:
| memoryCost (m) | timeCost (t) | parallelism (p) | Hash başına RAM |
|---|---|---|---|
| 47104 | 1 | 1 | 46 MiB |
| 19456 | 2 | 1 | 19 MiB (temel) |
| 12288 | 3 | 1 | 12 MiB |
| 9216 | 4 | 1 | 9 MiB |
| 7168 | 5 | 1 | 7 MiB |
Pratik ayarlama kuralı. m’i önce eşzamanlı giriş zirvesi RAM bütçenize göre seçin. 100 eşzamanlı giriş bekliyor ve 4 GiB ayırabiliyorsanız, bu hash başına 40 MiB demektir. Sonra üretim CPU’nuzda tek bir verify 100–500 ms sürene kadar t’yi artırın. Çok çekirdekli özel bir nedeniniz olmadıkça p=1 bırakın (çoğu web framework zaten her isteğe kendi thread’ini verir).
scrypt parametreleri: Argon2 mevcut olmadığında
OWASP’ın önerisi: N=2^17 (131072), r=8, p=1, hash başına 128 MiB kullanır.
Eşzamanlı giriş başına 128 MiB sunucunuz için fazlaysa, OWASP daha zayıf profillere izin verir:
| N | r | p | Hash başına RAM |
|---|---|---|---|
| 2^17 | 8 | 1 | 128 MiB (tercih edilen) |
| 2^16 | 8 | 1 | 64 MiB |
| 2^15 | 8 | 1 | 32 MiB |
N 2’nin kuvveti olmalıdır. r’yi artırmak hem bellek hem CPU işini orantılı olarak artırır; p’yi artırmak örnek başına belleği artırmadan CPU işini artırır. Parola hash’leme için r ve p’yi varsayılanlarda bırakın ve yalnızca N’yi ayarlayın.
bcrypt: cost factor 10+, yalnızca eski sistemler için
OWASP artık bcrypt’i yeni projeler için önermiyor, ancak hâlâ her yerde: Devise, Spring Security, ASP.NET Identity ve sayısız ev yapımı kimlik doğrulama sistemi varsayılan olarak onu kullanıyor.
bcrypt’e mahkumsanız, kurallar şunlar:
- Minimum bcrypt cost factor: 10. 10’un altı, tek bir GPU’nun sızdırılmış bir veritabanını günler içinde bitirebileceği kadar hızlıdır.
- Önerilen: donanıma göre 12 ila 14. Modern bir x86 sunucuda
cost=12hash başına yaklaşık 250 ms sürer;cost=13ise 500 ms. - Üretim donanımınızda her verify için 100–300 ms hedefleyin. Tahmin etmeyin, karşılaştırma yapın.
- 72 bayt giriş sınırını unutmayın. Kullanıcılar passphrase seçebiliyorsa, SHA-256 ile ön-hash’leyin (bkz. SSS).
bcrypt’in GPU direnci 4 KiB bellek ayak izi ile sınırlıdır. Hiçbir bcrypt cost faktörü Argon2id’nin bellek-zorluğuna asla ulaşamaz; yapabildiğinizde Argon2id’yi seçin.
Pratik bir referans: 2024 EPYC sunucusunda bcrypt(cost=12) kabaca 250 ms’de çalışır; üst seviye bir dizüstü bilgisayarda 350 ms’ye yakındır. Sayılarınız 100–500 ms aralığının dışına bir büyüklük mertebesi sapıyorsa, kütüphanenizin gerçekten yerel bcrypt yapıp yapmadığını veya yavaş bir JavaScript polyfill’e gerileyip gerilemediğini yeniden kontrol edin (bazı bundler’lar sunucusuz derlemelerde yerel bağımlılıkları temizler).
PBKDF2: FIPS-140 uyumluluk yolu
PBKDF2 (RFC 8018) güvenlik kılavuzu için son çare algoritmasıdır. bcrypt’ten daha eskidir, bellek-zor değildir ve GPU saldırılarına yukarıdaki üçünden daha hızlı düşer. Yine de FIPS-140 doğrulamalı olan tek parola hash’leme primitifidir; bu da federal hükümet, sağlık HIPAA ve belirli finansal dağıtımlar için önemlidir.
PBKDF2’ye ihtiyacınız olduğunda şunu kullanın:
- PRF olarak HMAC-SHA-256 (SHA-1 kullanmayın; HMAC olmadan düz SHA-256 kullanmayın)
- Minimum 600.000 iterasyon (OWASP 2026 temeli)
- Parola başına en az 16 baytlık rastgele bir salt
FIPS sizin için geçerli değilse, Argon2id’yi tercih edin. PBKDF2’nin sabit-çıktı, sabit-bellek tasarımı, bir saldırganın aldığı her dolarlık GPU silikonunun doğrudan saniye başına daha fazla parola tahmine dönüştüğü anlamına gelir.
NIST’in SP 800-63B belgesi PBKDF2-HMAC’ı parola hash’leme için “onaylanmış” olarak adlandırıyor, ancak bellek-zor alternatifler yerine onu önermekten kaçınıyor. Bunu şöyle okuyun: NIST PBKDF2’ye izin veriyor çünkü onu emekliye ayırmak her eski hükümet dağıtımını geçersiz kılar; yeşil saha proje için en iyi seçim olduğu için değil.
Karar çerçevesi: hangi algoritmayı seçmelisiniz
Karşılaştırma tablosu
| Boyut | bcrypt | scrypt | Argon2id | PBKDF2 |
|---|---|---|---|---|
| Bellek-zor | Hayır | Evet | Evet | Hayır |
| GPU direnci | Orta | Yüksek | Çok yüksek | Düşük |
| Yan kanal direnci | Orta | Orta | Yüksek (id) | Orta |
| Parametre karmaşıklığı | 1 (cost) | 3 (N, r, p) | 3 (m, t, p) | 1 (iterasyonlar) |
| Kütüphane olgunluğu | Mükemmel | İyi | İyi | Mükemmel |
| Giriş uzunluk sınırı | 72 bayt | Yok | Yok | Yok |
| Standartlaşma | de facto | RFC 7914 | RFC 9106 | RFC 8018 |
| OWASP 2026 durumu | Yalnızca eski | Alternatif | İlk tercih | Yalnızca FIPS |
Varsayılan olarak Argon2id kullanın
Yeni bir proje (tipik bir web uygulaması, modern Node/Python/Go/Rust/JVM yığını, FIPS kısıtlaması yok) için Argon2id’yi m=19456, t=2, p=1 ile kullanın. Mevcut en güçlü GPU ve yan kanal direncini, kütüphane yükseltmelerinden sağ çıkan gömülü parametreli bir formatı ve giriş uzunluğu sürprizi olmamasını alırsınız. Kütüphane ekosistemi olgun: npm’de argon2, PyPI’de argon2-cffi, golang.org/x/crypto/argon2, crates.io’da argon2 crate’i; hepsi bakımlı ve ölçülmüş.
Bunun yerine ne zaman scrypt veya bcrypt seçilir
scrypt’i şu durumda seçin: Argon2 çalışma zamanınızda mevcut değil (2026’da gerçekten nadir; Cloudflare Workers ve Deno bile artık ona sahip), ya da üretimde zaten scrypt tabanlı bir sisteminiz var ve geçiş maliyeti güvenlik farkından ağır basıyor. scrypt hâlâ sağlam bir algoritmadır; yalnızca Argon2id’nin yan kanal cilasından yoksundur.
bcrypt’i şu durumda seçin: Eski bir sistemi sürdürüyorsunuz, sıkı bir bağımlılık-azaltma gereksiniminiz var (yerel kod yok, ek paket yok) ve 72 bayt giriş sınırı kullanıcı tabanınız için kabul edilebilir. bcrypt yirmi yıldır internet ölçeğinde dağıtılıyor; başarısızlık modları iyi anlaşılmış.
PBKDF2’yi şu durumda seçin: Düzenleyici öyle dedi. Sebep budur. Denetçiniz Argon2id’yi kabul ediyorsa (FIPS olmayan iş yükleri için giderek artan sayıda kişi kabul ediyor), Argon2id’yi kullanın.
Kaçınılması gereken yaygın hatalar
Son on yıldaki çoğu parola depolama sızıntısı, küçük bir tekrarlayan mühendislik hatası kümesine kadar uzanıyor. Hiçbiri egzotik değil; aşağıdaki listeyi önünüzde tutarak kimlik doğrulama kodunuzu gözden geçirdiğinizde hepsi yakalanır.
- Parolaları ham SHA-256 veya MD5 ile hash’lemek. En büyük tek parola depolama başarısızlığı budur. Bunların parolalar için niye yanlış olduğuna dair MD5 vs SHA-256’ya bakın.
- Tüm kullanıcılarda tek bir global salt’ı yeniden kullanmak. Salt kayıt başına benzersiz olmak zorundadır. Argon2 ve bcrypt sizin için bir tane üretir; bunu geçersiz kılmayın.
- Hash süresini 50 ms’nin altına ayarlamak. Hiçbir kullanıcının fark edemeyeceği bir hız iyileştirmesi için güvenliği takas ettiniz. 100–500 ms hedefleyin.
- Hash süresini 1 saniyenin üzerine ayarlamak. Kendi giriş uç noktanıza karşı bir hizmet reddi vektörü oluşturdunuz. ~500 ms’de sınırlayın.
- Parolaları istemci tarafında hash’leyip sunucuya özet göndermek. Hash artık paroladır. Veritabanını çalan herkes onu hiç tersine çevirmeden kimlik doğrulayabilir. Her zaman sunucuda hash’leyin.
- Algoritma parametrelerini ayrı bir sütunda saklamak. PHC dize formatı bunları hash’in içine gömer. Onu kullanın.
- Hata işleme sırasında parolaları veya hash’leri loglamak. İkisi de kullanıcıya aittir, log toplayıcınıza değil. Bunları herhangi bir loglayıcıya ulaşmadan önce istek-ayrıştırma katmanında temizleyin.
verify()istisnalarını kimlik doğrulama hataları olarak değerlendirmek. Bozuk bir saklı hash üzerinde fırlatan bir kütüphane hatayı yüzeye çıkarmalı, sessizce “yanlış parolaya” düşmemelidir. “Yanlış parola” (401 döndür) ile “saklı hash bozuk” (500 döndür ve nöbetçiyi sayfaya çağır) arasında ayrım yapın.
Gerçek dünya uygulaması
Node.js’te Argon2id
argon2 paketi (referans uygulamasına yerel bağlamalar) Node’da kanonik seçimdir:
import argon2 from 'argon2';
// Hashing on signup or password change
const hash = await argon2.hash(password, {
type: argon2.argon2id,
memoryCost: 19456, // 19 MiB
timeCost: 2,
parallelism: 1,
});
// → '$argon2id$v=19$m=19456,t=2,p=1$<salt>$<hash>'
// Verifying on login
const ok = await argon2.verify(hash, candidate);
if (!ok) throw new Error('Invalid credentials');
// Detect outdated parameters and re-hash on successful login
if (argon2.needsRehash(hash, { type: argon2.argon2id, memoryCost: 19456, timeCost: 2, parallelism: 1 })) {
const upgraded = await argon2.hash(candidate, {
type: argon2.argon2id, memoryCost: 19456, timeCost: 2, parallelism: 1,
});
await db.users.update({ id: user.id }, { password_hash: upgraded });
}
needsRehash adımı uzun vadeli geçişin sırrıdır: her başarılı giriş, kullanıcıyı rahatsız etmeden saklı hash’i mevcut parametrelere yükseltme fırsatı haline gelir.
Aynı kalıp Python’da argon2-cffi ile:
from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError
ph = PasswordHasher(memory_cost=19456, time_cost=2, parallelism=1)
# Hash
stored = ph.hash(password)
# Verify
try:
ph.verify(stored, candidate)
except VerifyMismatchError:
raise ValueError('Invalid credentials')
# Re-hash on parameter upgrade
if ph.check_needs_rehash(stored):
stored = ph.hash(candidate)
Go’da golang.org/x/crypto/argon2 ile:
import (
"crypto/rand"
"golang.org/x/crypto/argon2"
)
func hashPassword(password string) ([]byte, []byte) {
salt := make([]byte, 16)
rand.Read(salt)
hash := argon2.IDKey([]byte(password), salt, 2, 19456, 1, 32)
return hash, salt
}
Go standart kütüphanesi PHC formatlı bir kodlayıcı ile gelmez; argon2.IDKey primitifini doğrudan kullanırsanız, parametreleri ve salt’ı hash ile birlikte kodlamaktan siz sorumlusunuz. Çoğu Go projesi bunun için github.com/alexedwards/argon2id gibi bir wrapper kullanır.
Rust’ta argon2 crate’i benzer şekilde idiomatiktir:
use argon2::{Argon2, PasswordHasher, PasswordVerifier, password_hash::{SaltString, rand_core::OsRng}};
let salt = SaltString::generate(&mut OsRng);
let argon2 = Argon2::default(); // Argon2id, m=19456, t=2, p=1 by default
let hash = argon2.hash_password(password.as_bytes(), &salt)?.to_string();
// On verify
let parsed = argon2::password_hash::PasswordHash::new(&hash)?;
argon2.verify_password(candidate.as_bytes(), &parsed)?;
Üç çalışma zamanında da üretilen dize değiştirilebilir: Node’da oluşturulmuş bir hash, Python veya Rust’ta sorunsuz doğrulanır. Bu çapraz çalışma zamanı uyumluluğu, Argon2’yi çok dilli mimariler için algoritmaya özgü wrapper’lardan daha güvenli bir bahis haline getirir.
bcrypt’ten Argon2id’ye geçiş kalıbı
Kullanıcı tablosunu silip baştan başlama şansınız neredeyse hiç olmaz. Doğru geçiş kalıbı, hash üreticimizin SSS’sindeki MD5’ten bcrypt’e bölümünde kullanılan kalıpla aynıdır: yumuşak, giriş güdümlü bir yükseltme.
Algoritmayı izleyen bir sütun ekleyin:
ALTER TABLE users ADD COLUMN password_algo VARCHAR(16) NOT NULL DEFAULT 'bcrypt';
Girişte doğru doğrulayıcıya yönlendirin:
async function verifyAndMaybeRehash(user, candidate) {
let ok;
if (user.password_algo === 'argon2id') {
ok = await argon2.verify(user.password_hash, candidate);
} else if (user.password_algo === 'bcrypt') {
ok = await bcrypt.compare(candidate, user.password_hash);
if (ok) {
// Successful legacy verify → re-hash with Argon2id
const newHash = await argon2.hash(candidate, {
type: argon2.argon2id, memoryCost: 19456, timeCost: 2, parallelism: 1,
});
await db.users.update({ id: user.id }, {
password_hash: newHash,
password_algo: 'argon2id',
});
}
}
return ok;
}
6–12 aylık bir kapanış penceresi belirleyin. 9’uncu ay işaretinde “parolanız güncel olmayan bir yöntemle saklanıyor, yükseltmek için lütfen giriş yapın” e-postası gönderin. 12 ayın sonunda hâlâ bcrypt’te olan hesaplar, sonraki girişte zorunlu parola sıfırlama gerektirir. Aktif kullanıcılar şeffaf şekilde geçer; aktif olmayan hesaplar tek seferlik bir sürtünme olayı yaşar.
Aynı kalıp scrypt veya PBKDF2’den geçiş için de işe yarar. İhtiyacınız olan tek şey password_algo sütunudur.
Pepper, uzunluk sınırları ve kodlama tuzakları
Gerçek dağıtımları ısıran birkaç keskin köşe:
Pepper. Pepper, hash’lemeden önce her parolaya eklenen, veritabanından ayrı saklanan (KMS, ortam değişkeni veya Hashicorp Vault) bir uygulama düzeyi sırrıdır. Veritabanınız sızar ama uygulama sırrınız sızmazsa, sızdırılmış hash’ler pepper olmadan saldırılamaz. Bunu birleştirme olarak değil, HMAC olarak uygulayın:
import { createHmac } from 'crypto';
const peppered = createHmac('sha256', process.env.PEPPER).update(password).digest();
const hash = await argon2.hash(peppered, { type: argon2.argon2id, /* ... */ });
Pepper’ı nadiren döndürün (yeniden hash’leme gerektirir) ancak versiyonlayarak döndürmeyi destekleyin: PEPPER_V2, doğrulamada PEPPER_V1’e geri dönüş ile.
bcrypt 72 bayt sınırı. bcrypt kullanmanız gerekiyorsa ve isteğe bağlı uzunlukta parolaları desteklemek istiyorsanız, SHA-256 ile ön-hash’leyin ve base64-kodlayın (bcrypt’in tutarsız şekilde işlediği gömülü NUL baytlarından kaçınarak):
import { createHash } from 'crypto';
const prepped = createHash('sha256').update(password, 'utf8').digest('base64');
const hash = await bcrypt.hash(prepped, 12);
Aynı prepped dönüşümü doğrulamada da çalışmalıdır. Bunu kimlik doğrulama kodunuzda dev bir yorumla belgeleyin; gelecekteki siz, şimdiki size teşekkür edecek.
UTF-8 normalleştirme. "café" karakter dizisi ya c-a-f-é (4 codepoint, NFC) ya da c-a-f-e + birleştirici akut (5 codepoint, NFD) olarak kodlanabilir. Aynı görünürler ama farklı hash’ler üretirler. Hash’lemeden önce her zaman NFC’ye normalleştirin:
const normalized = password.normalize('NFC');
Bu, beklediğinizden daha sık mobil klavyeleri ve PDF’lerden kopyala-yapıştırı ısırır.
İstemcide asla ön-hash’lemeyin. Sunucuya gönderilen istemci-hesaplı bir hash, yeni paroladır. Veritabanınızı okuyan herkes kimlik doğrulayabilir. Sunucuda hash’leyin, son. JWT’ler bunu değiştirmez; JWT’lerin neyi doğrulayıp doğrulamadığı için JWT Token Nasıl Çözülür’e bakın.
Dizüstü bilgisayarınızda değil, üretim donanımında karşılaştırma yapın. 13. nesil Intel dizüstünde Argon2id’yi m=19456, t=2, p=1 ile çalıştırmak kabaca 35 ms’de biter. Aynı parametreler t3.small EC2 örneğinde 180 ms’ye yakın sürer; Raspberry Pi 4’te 600 ms’nin üzerinde. Üretimi gerçekten çalıştıracak donanımı seçin, 1.000 doğrulamayı zamanlayın ve medyandan ayarlayın. Soğuk-başlangıç sunucusuz konteynerlerinden gelen giriş gecikme varyansı da ölçülmeye değer; Lambda soğuk başlangıçları, hash’leme ile alakasız 200–800 ms ekleyebilir.
SSS
Parola hash’leme ile şifreleme arasındaki fark nedir
Hash’leme tek yönlüdür: girdiyi geri kurtarmak için tersine çevrilemeyen sabit uzunlukta bir parmak izi hesaplarsınız. Şifreleme iki yönlüdür: doğru anahtarla orijinale geri çözebilirsiniz. Parolalar şifrelenmemeli, hash’lenmelidir. Bir sunucu hiçbir kullanıcının parolasını kurtarabilmemelidir, böylece bir veritabanı sızıntısı bir kimlik bilgisi sızıntısına dönüşmez.
Parolalar için niye yalnızca SHA-256 kullanamıyorum
SHA-256 hız için tasarlanmıştır. Modern bir GPU saniyede 22 milyar SHA-256 hash hesaplar; bu da sızdırılmış bir veritabanından 8 karakterlik küçük harf bir parolanın dakikalar içinde düştüğü anlamına gelir. Parola hash’lerinin SHA-256’da olmayan üç özelliğe ihtiyacı vardır: kasıtlı olarak yavaş yürütme, kayıt başına salt ve bellek-zorluk. Tradeoff ilkesi, hash üreticimizin “Don’t Use MD5 for Security” rehberinde açıklananla aynıdır; saldırganların zayıf hash’leri düz metne nasıl çevirdiği hakkında daha fazlası için Parola Entropy’si’ne bakabilirsiniz.
bcrypt 2026’da hâlâ güvenli mi
bcrypt’in kendisi kırılmadı. Blowfish tabanlı anahtar zamanlaması kriptografik olarak sağlam kalmaya devam ediyor. Değişen şey tehdit modeli: GPU’lar ve ASIC’ler, bcrypt’in bellek-zorluk eksikliğini Argon2id’ye kıyasla anlamlı bir zayıflık haline getiriyor. OWASP’ın 2026 tutumu şudur: bcrypt cost ≥ 10 ile eski sistemler için kabul edilebilir, ancak yeni projeler Argon2id’yi seçmelidir.
Argon2i, Argon2d ve Argon2id: hangisini kullanmalıyım
Argon2id’yi kullanın. RFC 9106 onu parola hash’leme için önerilen varyant olarak belirtir. Argon2i veriden bağımsızdır (yan kanal güvenli ama GPU tradeoff saldırılarına karşı daha zayıf). Argon2d veriye bağımlıdır (GPU’ya karşı güçlü ama önbellek zamanlama yan kanallarına karşı savunmasız). Argon2id, her iki özelliği birinin fiyatına alan bir hibrittir.
Uygulamam için Argon2id parametrelerini nasıl seçerim
OWASP temeli ile başlayın: m=19456, t=2, p=1. Sonra üretim CPU’nuzda karşılaştırma yapıp ayarlayın:
- Giriş başına RAM bütçenize karar verin (örn. zirve eşzamanlılıkta 50 MiB).
m’i bu değere veya altına ayarlayın.argon2.hash()’i bir döngüde çalıştırıp duvar saatini ölçün.- Medyan 100 ile 500 ms arasında olana kadar
t’yi artırın.
Profilleme yapıp çok şeritli paralelliğin çalışma zamanınıza yardımcı olduğunu bilmedikçe p=1 bırakın. Yüksek trafikli kimlik doğrulama sunucuları için, daha yüksek t ve daha düşük m lehine eğilmek genellikle daha iyi RAM payı verir.
bcrypt’in 72 bayt sınırı nedir ve uzun passphrase’leri nasıl ele alırım
bcrypt girdisini Blowfish anahtar zamanlamasına besler ve bu da 72 baytta kırpar. 150 karakterlik bir passphrase, ilk 72 baytı ile aynı güvenliğe sahiptir; gerisi yok sayılır. Düzeltme: SHA-256 (32 bayt) veya SHA-512 (64 bayt) ile ön-hash’lemek, NUL baytlarından kaçınmak için özeti base64-kodlamak ve onu bcrypt’e beslemektir. Argon2id ve scrypt’in böyle bir sınırı yoktur; isteğe bağlı uzunluktaki girdiyi doğrudan kabul ederler.
Parola sıfırlatmadan bcrypt’i Argon2’ye geçirebilir miyim
Evet. Kalıp şudur: her iki algoritmayı bir password_algo sütununun arkasında saklayın, doğrulamayı doğru kütüphaneye yönlendirin ve her başarılı bcrypt doğrulamasında hemen Argon2id ile yeniden hash’leyip satırı güncelleyin. Aktif kullanıcılar normal giriş kadansları içinde sessizce geçerler. Aktif olmayan hesaplar için 6–12 aylık bir kapanış penceresi belirleyin, ardından hâlâ bcrypt üzerinde olan herhangi bir kayıt için parola sıfırlamayı zorlayın. Aynı kalıp herhangi bir algoritmadan algoritmaya geçiş için işe yarar.
PBKDF2 2026’da hâlâ iyi bir seçim mi
Yalnızca FIPS-140 uyumluluğu elinizi zorladığında: federal hükümet, düzenlenmiş sağlık (HIPAA) ve belirli finansal sistemlerde tipik. PRF olarak HMAC-SHA-256’yı en az 600.000 iterasyonla kullanın. PBKDF2 bellek-zor değildir, bu yüzden eşdeğer gecikme bütçelerinde GPU saldırılarına Argon2id’den daha hızlı düşer. FIPS geçerli değilse, Argon2id’yi seçin ve uyum cimnastiğini atlayın.
2026 parola hash’leme cevabı kısa: varsayılan olarak Argon2id’yi OWASP’ın temel parametreleriyle kullanın, Argon2 mevcut değilse scrypt’e geri dönün, bcrypt’i yalnızca eski sistemlerin gerektirdiği yerde tutun ve PBKDF2’yi FIPS bağımlı sistemler için ayırın. Hash’i kayıt başına bir salt (her modern kütüphane bunu otomatik halleder), veritabanı dışında saklanan uygulama düzeyi bir pepper ve donanım geliştikçe iş faktörlerini yükseltmenize izin veren giriş güdümlü bir yeniden hash döngüsü ile eşleştirin.
Rastgele Şifre Üretici ile temsili bir parola seti üretin, doğrulama yolunuzu üretim CPU’nuza karşı karşılaştırın ve parametreleri bir sabitler dosyasına yazın; böylece bir sonraki mühendis 2028’de tam olarak neyi yükselteceğini bilir. Tam güvenlik bağlamı (TLS, oturum yönetimi, hız sınırlama, MFA) Web Güvenliği Temelleri rehberimizde yaşıyor. Uygulamanız için doğru hash’i bugün seçin.