Veri tabanında şifre depolarken farklı yaklaşımlar kullanılmaktadır. Bu yazımda biraz bunlara değineceğim.
Hash Kullanmak
Avantajları;
- Şifre veri tabanında depolanmaz.
- Şifre uzunluğu tahmin edilemez.
Dezavantajları;
- Şifre geri dönüştürülemediği için kullanıcı şifresini unutursa yeniden şifre yaratmak gerekir.
- Farklı iki kullanıcı aynı şifreyi kullanırsa aynı değer üretilir. Bunu aşmak için salt kullanmak gerekir.
- MD5 gibi algoritmalar kullanılırsa, brute force atakları ile şifre bulunabilir.
public class StorePassword { public static byte[] HashPasswordWithSalt(byte[] toBeHashed, byte[] salt) { using (var sha256 = SHA256.Create()) { return sha256.ComputeHash(Combine(toBeHashed, salt)); } } private static byte[] Combine(byte[] first, byte[] second) { var ret = new byte[first.Length + second.Length]; Buffer.BlockCopy(first, 0, ret, 0, first.Length); Buffer.BlockCopy(second, 0, ret, first.Length, second.Length); return ret; } public static byte[] GenerateSalt() { const int SALT_LENGTH = 32; using (var randomNumberGenerator = new RNGCryptoServiceProvider()) { var randomNumber = new byte[SALT_LENGTH]; randomNumberGenerator.GetBytes(randomNumber); return randomNumber; } } }
static void Main(string[] args) { #region testStorePassword string password = "erkanliman.com"; byte[] salt = StorePassword.GenerateSalt(); var passwordHash = StorePassword.HashPasswordWithSalt(Encoding.UTF8.GetBytes(password), salt); Console.WriteLine("Şifre: " + password); Console.WriteLine("salt: " + Convert.ToBase64String(salt)); Console.WriteLine("Hashli Şifre: " + Convert.ToBase64String(passwordHash)); #endregion }
Çıktı:
Şifre Bazlı Key Üretme
public class passwordBasedKey { public static byte[] GenerateSalt() { using (var randomNumbers = new RNGCryptoServiceProvider()) { var randomNumber = new byte[32]; randomNumbers.GetBytes(randomNumber); return randomNumber; } } public static byte[] HashPassword(byte[] toBeHashed, byte[] salt, int numberOfRounds) { using (var rfc2898 = new Rfc2898DeriveBytes(toBeHashed, salt, numberOfRounds)) { return rfc2898.GetBytes(32); } } }
private static void HashPassword(string passwordToHash, int numberOfRounds) { var sw = new Stopwatch(); sw.Start(); var hashedPassword = passwordBasedKey.HashPassword(Encoding.UTF8.GetBytes(passwordToHash), passwordBasedKey.GenerateSalt(), numberOfRounds); sw.Stop(); Console.WriteLine(); Console.WriteLine("Şifre : " + passwordToHash); Console.WriteLine("Hashli Şifre : " + Convert.ToBase64String(hashedPassword)); Console.WriteLine("İterasyon <" + numberOfRounds + "> Zaman : " + sw.ElapsedMilliseconds + "ms"); }
static void Main(string[] args) { #region testpasswordBasedKey var passwordToHash = "erkanliman.com"; HashPassword(passwordToHash, 100); HashPassword(passwordToHash, 1000); HashPassword(passwordToHash, 10000); HashPassword(passwordToHash, 100000); HashPassword(passwordToHash, 1000000); HashPassword(passwordToHash, 10000000); #endregion }
Çıktı:
Bir yanıt yazın