Read in 13 min read, written by Emre Cebeci

TABLE OF CONTENTS

Argon2 vs bcrypt: .NET’te Temel Parola Hashleme Rehberi

Giriş: Neden Parola Hashleme?

Kullanıcı parolalarını düz metin (plain-text) olarak saklamak ciddi bir güvenlik açığıdır. Bir veri ihlali durumunda, parolalar doğrudan kötü niyetli kişilerin eline geçebilir. Parola hashleme, bu riski ortadan kaldırmak için kullanılır. Parola, tek yönlü (one-way) fonksiyonlardan geçirilir ve geri çözülemez hale gelir.

Algoritmalara Genel Bakış

bcrypt Nedir?

bcrypt, Blowfish algoritması temelli bir parola hashleme fonksiyonudur. 1999 yılında tanıtılmıştır ve yıllarca endüstri standardı olmuştur. Ana parametresi cost değeridir. Bu değer, hash fonksiyonunun kaç kez çalıştırılacağını belirler ve doğrudan işlem süresini etkiler.

Avantajları:

  • Kullanımı basittir
  • Legacy sistemlerde güvenli kabul edilir.

Dezavantajları:

  • Hash üretimi sırasında bellek tüketimi düşüktür → Bu da özellikle GPU ile yapılan brute-force saldırılarına karşı daha savunmasız olmasına neden olur
  • Sadece cost parametresi alabilir, parametre esnekliği düşüktür.

Argon2 Nedir?

Argon2, 2015'te Password Hashing Competition (PHC) kazananı olan modern bir algoritmadır. 3 türe sahiptir:

  • argon2d: GPU saldırılarına dayanıklıdır ancak side-channel’a açık olabilir
  • argon2i: Side-channel’a karşı dayanıklı, bellek erişimi rastgele yapılır
  • argon2id: argon2d ve argon2i’nin hibrit biçimidir. Hem güvenli hem dengelidir → önerilen türdür

Avantajları:

  • Bellek ve CPU dostu, özelleştirilebilir parametrelerle çalışır
  • GPU gücü ile yapılan saldıralara karşı daha dayanıklı
  • Modern güvenlik standartlarına uygundur.

Dezavantajları:

  • bcrypt’a göre başlangıçta doğru parametrelerle yapılandırılması gerekir
  • Farklı ortamlarda tutarlılık sağlamak için ayarların dikkatle seçilmesi gerekir.

OWASP Tavsiyeleri

OWASP’in Parola Hashleme Tavsiyesi

Bu karşılaştırmayı yaparken OWASP’in önerilerini temel aldım. OWASP diyor ki:

Parolalar saklandığında, uygulama veya veritabanı tehlikeye girse bile bir saldırgandan korunmalıdır.

Yani işin özü şu: parola hashlemek sadece parolayı gizlemek değil; veri tabanı ele geçirilirse saldırganın işini iyice zorlaştırmak demektir.

Bu noktada Argon2, modern ve güçlü bir algoritma olarak öne çıkıyor. Eğer Argon2 kullanılamıyorsa, OWASP scrypt’i öneriyor.

Yine de, bcrypt hâlâ birçok legacy sistemde de facto standart. Bu yüzden bu yazıda Argon2 ile bcrypt’i, OWASP’in önerdiği ayarlarla karşılaştıracağım.

Benchmark Sonuçları

BenchmarkDotNet paketiyle gerçekleştirdiğim testlerde, Argon2id algoritması OWASP’nin önerdiği minimum ayarlarla çalıştırıldığında bcrypt’e kıyasla yaklaşık %47.5 daha yavaş (85.08 ms vs. 57.70 ms) sonuç vermektedir. Ancak lane değeri 2 yapıldığında bu fark %3.5 seviyelerine (59.75 ms vs. 57.70 ms) kadar düşmektedir.

Bu da gösteriyor ki: doğru parametre seçimi kritik öneme sahiptir. Yanlış yapılandırmalar ya performansı düşürebilir ya da güvenlik seviyesini zayıflatabilir.

Testte kullanılan Argon2CustomHash methodunu düzenleyerek, farklı ayarlarla performans karşılaştırması yapabilir ve kendi sisteminize en uygun konfigürasyonu belirleyebilirsiniz.

Benchmark sonuçları

.NET’te Uygulamak

.NET’te bcrypt ve Argon2 Paketlerinin Kurulumu

bcrypt için BCrypt.Net-Next paketini kullandım.

bashdotnet add package BCrypt.Net-Next

Argon2 için Isopoh’un paketini kullandım

bashdotnet add package Isopoh.Cryptography.Argon2

bcrypt ile Parola Hashleme & Doğrulama

c#public class PasswordHasher
{
    public string BcryptHash(string password)
    {
        return BCrypt.Net.BCrypt.HashPassword(password, workFactor: 12); // OWASP minimum 10 önerir
    }
    public bool BcryptVerify(string password, string hashedPassword)
    {
        return BCrypt.Net.BCrypt.Verify(password, hashedPassword);
    }
}

Argon2id ile Parola Hashleme & Doğrulama

c#using Isopoh.Cryptography.Argon2;
public class PasswordHasher
{
    // Hashleme (OWASP Ayarları: 19 MiB bellek, 2 iterasyon, 1 paralellik)
    public static string Argon2Hash(string password)
    {
        // Rastgele salt olustur
        var salt = GenerateSalt(16);
        var argon2Config = new Argon2Config
        {
            Type = Argon2Type.HybridAddressing, // Argon2id
            Password = System.Text.Encoding.UTF8.GetBytes(password),
            MemoryCost = 19456, // 19 MiB (19456 KB)
            TimeCost = 2,
            Lanes = 1, // Paralellik
            Threads = 1, // Thread sınırı
            HashLength = 32,
            Salt = salt
        };
        var argon2A = new Argon2(argon2Config);
        using (SecureArray<byte> hashA = argon2A.Hash())
        {
            return argon2Config.EncodeString(hashA.Buffer);
        }
    }
    // Doğrulama
    public bool Argon2Verify(string password, string hashedPassword)
    {
        return Argon2.Verify(hashedPassword, password);
    }

    // Salt oluşturma
    private static byte[] GenerateSalt(int size = 16)
    {
        var salt = new byte[size];
        using (var rng = System.Security.Cryptography.RandomNumberGenerator.Create())
        {
            rng.GetBytes(salt);
        }
        return salt;
    }
}

Gelişmiş Konular

Password Rehashing: Parolaları Sessizce Yeniden Hashlemek

Yeni algoritma ya da parametrelerle daha güvenli veya hızlı bir parola hashleme yapılandırmasına geçtiğinizde, eski parolalar hâlâ eski ayarlarla saklanmaya devam eder. Çünkü hash işlemi tek yönlüdür — yani bir parolayı yeniden yapılandırmak için onu tekrar düz metin hâlinde bilmeniz gerekir. Ama veritabanınızda sadece hash vardır, parola yoktur.

İşte bu noktada devreye “password rehashing” girer. Kullanıcı sisteme giriş yaptığında, yani parolasını doğru şekilde girdiğinde, bu fırsatı değerlendirip parolayı yeni algoritma veya parametrelerle yeniden hashleyebilirsiniz. Bu işlem arka planda sessizce gerçekleşir ve kullanıcı herhangi bir şey fark etmez.

RFC 9106: İleri Okuma Önerisi

RFC 9106, Argon2'in teknik detaylarını ve parametre optimizasyonunu açıklar. Özelliklikle Section 4, Parametre seçiminin güvenlik üzerindeki etkilerini analiz etmektedir. RFC 9106'nın teknik tavsiyelerini inceleyerek parametreleri ölçeklendirebilirsiniz.

https://datatracker.ietf.org/doc/html/rfc9106#section-4

Bonus: bcrypt’in 72 Byte Sınırı Hakkında

bcrypt algoritmasının çoğu implementasyonunda, hashleme işlemi sadece parolanın ilk 72 byte’ını dikkate alır. Yani 72 byte sonrasını hesaplama işlemine dahil etmez. Burada ayrıca önemi olan husus: 72 sayısı karakter sayısı değil, byte sınırıdır.

  • ASCII karakterler genelde 1 byte yer kaplar, bu nedenle yalnızca ASCII karakterlerden oluşan bir parola en fazla 72 karakter uzunluğunda olmalıdır.
  • Ancak ş, ü, ğ, , 😊 gibi ASCII dışı karakterler UTF-8 kodlamada 2 ile 4 byte yer kaplar. Bu durumda aynı sınır, çok daha kısa karakter uzunluklarında aşılabilir.

Örnekler:

abcABC123! → 10 karakter, tamamı ASCII → 10 byte

şifreGüçlü!

  • ‘ş’, ‘ü’, ‘ç’, ‘ü’ Türkçe karakterleri UTF-8'de 2 byte yer kaplar → 4 × 2 = 8 byte
  • Diğer 7 karakter ASCII’dir → 7 × 1 = 7 byte
  • Toplam 15 byte

“Parola😊123”

  • 9 ASCII karakter → 9 byte
  • Emoji (😊) → 4 byte
  • Toplam 13 byte

Bu nedenle bcrypt kullanan sistemlerde 72 karakter sınırı koymak yanıltıcı olabilir. Bu sınırı karakter sayısına göre değil, byte cinsinden kontrol etmek gerekir. Aksi takdirde parolanın sonunda 72 byte sonrasındaki karakterler truncate edilir ve bu çok düşük bir olaslık da olsa güvenlik açığına yol açabilir.

Tabii ki 72 byte veriden collision saldırısı gibi bir şeyin mümkün olup olmayacağı ayrı bir tartışma konusudur.

Sonuç

Güvenlik, algoritma seçiminin yanı sıra bu seçimin OWASP standartlarına uygun parametrelerle desteklenmesiyle sağlanır.

Parola güvenliğinde doğru algoritma seçimi, sisteminizin direncini belirleyen kritik bir adımdır. Argon2id, OWASP tarafından açıkça önerilen modern bir seçenek olarak öne çıkıyor; GPU tabanlı saldırılara karşı üstün direnci, bellek optimizasyonu ve parametre esnekliğiyle güvenlikle performansı dengeliyor. Doğru yapılandırıldığında, bcrypt’ten yalnızca %3.5 daha yavaş çalışarak kaynak tüketimini makul seviyede tutabilir. Lakin o testte Argon2id, bcrypt’e kıyasla 20.000 kat daha fazla bellek daha fazla bellek kullanır, bu da düşük kaynaklı sistemlerde performans sorunlarına yol açabilir. Argon2, yüksek bellek tüketimiyle saldırganların özel donanım (GPU/ASIC) avantajını kırmayı amaçlayan kasıtlı bir tasarım benimser.

Ancak bcrypt, basit yapısı ve yaygın legacy destekle hâlâ geçerli bir alternatif; özellikle OWASP’in belirttiği work factor'ü 10 veya üzeri ile saldırı maliyeti artırılabilir.

OWASP, yeni sistemlerde Argon2id kullanımını mümkün olduğunca zorunlu kılarken, geçiş sürecinde kullanıcı girişlerinde “rehashing” ile eski hashleri sessizce güncellemeyi önerir. Sonuç olarak, yüksek güvenlik gerektiren projelerde OWASP’in belirlediği Argon2id parametreleri temel alınmalı; eski sistemlerde bcrypt kullanılıyorsa work factor tavsiye edilen değerde tutulmalıdır.

Not: OWASP’in güncel kılavuzlarını takip etmek ve düzenli denetimler yap(tır)mak, sisteminizi gelecekteki tehditlere karşı korumanın en etkili yoludur. Bu makalede yer alan bilgiler ve bulgular zamanla geçerliliğini yitirebilir.

Kaynaklar

OWASP Top 10

Password Storage - OWASP Cheat Sheet Series

GitHub - mheyman/Isopoh.Cryptography.Argon2: Fully managed .Net Core implementation of Argon2

RFC 9106: Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications

GitHub - Dotnet Argon2 Bcrypt Benchmark

© M. Emre Cebeci. All Rights Reserved
Contact MeEmail This Page
Cookie Policy