12 Aralık 2020 Cumartesi

Hashing için Tuzlama

 Düz hashing ile temel sorun belirli bir çıktının karşılık gelen girdiye eşlenmesidir. Önceden hesaplanabilir ve saklanabilir. Bu soruna kolay bir çözüm tuzlamadır. Eklenen rastgele bir dizenin hashing işleminden önce veriler eklenir böylece çıktı önceden hesaplanmış eşlemeler kullanılarak geriye döndürülemez. Sözlüğe dayalı saldırılar dahil olmak üzere hash üzerindeki tüm saldırılar istinalar dışında etkisiz hale getirilir. 


Tuz değerini daha uzun tutmak her mesaj için benzersiz bir tuz değeri kullanmak önemlidir.


Saldırgan kaba kuvvet saldırısı düzenler ve arama tablolarını kullanarak saldırı sürecini ileri almasını sağlar.  Kaba kuvvet saldırısı yapılabilen anahtar germe diye bilinen bir teknik vardır.  Bu işlem o kadar işi yavaşlatacak ki, hash'i kırmak en azından bir saldırgan bakış açısından birkaç ay onu kırmamak kötü sonuçları beraberinde getirecektir.


Parola Tabanlı Anahtar Türetme İşlevi 2 (PBKDF2) RSA  nin bir parçası olan anahtar türetme işlevidir. PKCS serisinin PKCS # sürümü 2.yayınlanmış,RFC 2898 olarak üretilen bir önceki standart olan PBKDF1 in yerini almıştır.  160 bit uzunluğa kadar türetilmiş anahtarlardır.


PBKDF2 algoritması benzer anahtar genişletme içi  standart algoritmalar bulunur. Girdiyi hash eder bir tuz değeri ile birlikte şifre veya verileri türetilmiş bir anahtar oluşturur ve bu işlemi bir çok kez tekrar eder.


Hashing , Brute-Force saldırıları bir saldırgan için zaman alıcı ve sinir bozucu hale getirir. Önerilen yineleme sayısı 1000 dir. Yineleme sayısı ne kadar yüksekse o kadar daha fazla CPU gücüne ve zamana ihtiyacı olması gerekir. Ancak bu işlemlerle verilerimizi daha güvenli hale getirebileceğiz. 


Tuzlama (Salt) ve PBKDF2 kullanarak bir SHA-1 hash oluşturulan kod aşağıda örnek amacıyla paylaşılmıştır. Rfc2898DeriveBytes sınıfı SHA-1 tabanlıdır. Bunun sonucunda elde edilen karma değer örnekteki gibi SHA256 değil, SHA-1 dir.


string data = "hello";
byte[] salt = new Byte[32];
using (var provider = new RNGCryptoServiceProvider())
{
provider.GetBytes(salt);
}
Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(data, salt);
pbkdf2.IterationCount = 1000;
byte[] hash = pbkdf2.GetBytes(32);
string hashString = Convert.ToBase64String(hash);
 
 


Bu adımları nasıl kullanabileceğimiz için küçük bir alıştırma; Kullanıcı tablomuzda user_id ve password sütunlarına sahip olduğumuzu düşünelim bir sütun daha ekleyelim. Salt ve Store_hashString. Tuz değerini olduğu gibi saklayabiliriz. Bayt dizisi şeklinde, Onu bsa64 olarak kodlayabiliriz.

Kullanıcı yeniden oturum açmak istediğinde kullanıcı kimlik bilgilerini nasıl doğrulayacağının yolunu bulacağız.


string password = String.Empty; // Placeholder, şifreyi databaseden alıyoruz.
string saltString = String.Empty; // Placeholder, salt değeri databaseden alıyoruz.
string userEnteredPassword = String.Empty; // User input
var pbkdf2 = new Rfc2898DeriveBytes(userEnteredPassword, Convert.FromBase64String(saltString));
pbkdf2.IterationCount = 1000;
byte[] computedHash = pbkdf2.GetBytes(32);
bool isAuthenticCredential = password.Equals(
Convert.ToBase64String(computedHash),
StringComparison.Ordinal);


Not:

Veritabanındaki verileri şifrelemek için anahtara ihtiyacınız olacaktır. Bu anahtarı kesinlikle veritabanında saklamayın. Eğer Veritabanı SQL Injection v.b tehlikelere girerse saldırgan anahtarı ele geçirecek ve veritabanındaki şifrelerinin çözülmesi mümkün olacaktır. 


Hiç yorum yok:

Yorum Gönder