Wikipedia'da bakabilirsiniz ... Ama bir açıklama istediğiniz için burada elimden geleni yapacağım:
Karma İşlevleri
Bunlar, rasgele uzunluk girişi ile (genellikle) sabit uzunluk (veya daha küçük uzunluk) çıkışı arasında bir eşleme sağlar. Basit bir crc32'den, MD5 veya SHA1 / 2/256/512 gibi tam gelişmiş bir şifreleme karma işlevine kadar herhangi bir şey olabilir. Mesele şu ki, tek yönlü bir harita var. Her zaman çoktur: 1 eşleme (her zaman çarpışma olacaktır) çünkü her işlev girebildiğinden daha küçük bir çıktı üretir (Mümkün olan her 1mb dosyasını MD5'e beslerseniz, bir ton çarpışma elde edersiniz).
Tersine çevirmenin zor (veya pratik olarak imkansız) olmasının nedeni, dahili olarak nasıl çalıştıklarıdır. Çoğu kriptografik hash fonksiyonu, çıktıyı üretmek için birçok kez girdi setini tekrarlar. Dolayısıyla, girişin her bir sabit uzunluklu yığınına (algoritmaya bağlı olan) bakarsak, hash fonksiyonu buna mevcut durumu çağıracaktır. Daha sonra durum üzerinde yinelenir ve yeni bir duruma dönüştürülür ve bunu kendi başına geri bildirim olarak kullanır (MD5 bunu her 512 bit veri parçası için 64 kez yapar). Daha sonra, sonuçta hash oluşturmak için tüm bu iterasyonlardan elde edilen durumları bir şekilde birleştirir.
Şimdi, karmanın kodunu çözmek istiyorsanız, önce verilen karmanın yinelenen durumlarına nasıl bölüneceğini anlamanız gerekir (birçoğu daha büyük girdiler için, bir veri parçasının boyutundan daha küçük girişler için 1 olasılık). O zaman her durum için yinelemeyi tersine çevirmeniz gerekir. Şimdi, bu çok zor neden anlamak çalışırken hayal açıklamak a
ve b
aşağıdaki formülden: 10 = a + b
. 10 pozitif kombinasyon vardır a
ve b
bu işe yarayabilir. Şimdi bir sürü kez döngü yapalım:tmp = a + b; a = b; b = tmp
. 64 yineleme için denemeniz için 10 ^ 64'den fazla seçeneğiniz vardır. Ve bu sadece bazı devletlerin yinelemeden yinelemeye kadar korunduğu basit bir ekleme. Gerçek karma işlevleri 1'den fazla işlem yapar (MD5, 4 durum değişkeninde yaklaşık 15 işlem yapar). Ve bir sonraki yineleme, bir önceki ve bir önceki durumun durumuna bağlı olduğundan, bir önceki durumun yaratılmasında yok edildiğinden, belirli bir çıkış durumuna yol açan giriş durumunu belirlemek imkansızdır (her yineleme için daha az değildir). Bunu, çok sayıda olasılıkla birleştirin ve bir MD5'in bile kodunun çözülmesi neredeyse sonsuz miktarda (ancak sonsuz değil) kaynak gerektirecektir. O kadar çok kaynak var ki,
Şifreleme İşlevleri
Rasgele uzunluk girişi ve çıkışı arasında 1: 1 eşleme sağlarlar. Ve her zaman geri dönüşümlüdürler. Unutulmaması gereken önemli olan, bazı yöntemlerle tersinir olmasıdır. Ve verilen bir anahtar için her zaman 1: 1'dir. Şimdi, birden fazla girdi var: aynı çıktıyı üretebilecek anahtar çiftleri (aslında şifreleme işlevine bağlı olarak genellikle vardır). İyi şifrelenmiş veriler rastgele gürültüden ayırt edilemez. Bu her zaman tutarlı bir formatta olan iyi bir karma çıktıdan farklıdır.
Kullanım Örnekleri
Bir değeri karşılaştırmak istediğinizde ancak düz temsili saklayamadığınızda (herhangi bir nedenden dolayı) bir karma işlevi kullanın. Güvenlik nedenleriyle düz metin saklamak istemediğiniz için parolalar bu kullanım senaryosuna çok iyi uymalıdır (ve olmamalıdır). Ama korsan müzik dosyaları için bir dosya sistemini kontrol etmek isteseydiniz? Müzik dosyası başına 3 mb saklamak pratik olmaz. Bunun yerine, dosyanın karmasını alın ve saklayın (md5, 3mb yerine 16 bayt depolar). Bu şekilde, sadece her dosyayı hash yapar ve saklanan karma veritabanıyla karşılaştırırsınız (Bu, yeniden kodlama, dosya başlıklarını değiştirme vb. Nedeniyle pratikte iyi çalışmaz, ancak örnek bir kullanım örneği).
Giriş verilerinin geçerliliğini kontrol ederken bir karma işlevi kullanın. Bunun için tasarlandılar. 2 adet girişiniz varsa ve bunların aynı olup olmadığını kontrol etmek istiyorsanız, her ikisini de bir karma işleviyle çalıştırın. Çarpışma olasılığı, küçük girdi boyutları için astronomik olarak düşüktür (iyi bir hash fonksiyonu olduğu varsayılarak). Bu yüzden şifreler için önerilir. 32 karaktere kadar parolalar için, md5 çıkış alanının 4 katına sahiptir. SHA1, çıkış alanının 6 katına sahiptir (yaklaşık olarak). SHA512'nin çıktı alanının yaklaşık 16 katı vardır. Parolanın ne olduğunu gerçekten umursamıyorsunuz , saklanan parola ile aynı olup olmadığını önemsiyorsunuz. Bu yüzden parolalar için karma kullanmalısınız.
Giriş verilerini geri almak istediğinizde şifreleme kullanın. Kelime ihtiyacına dikkat edin . Kredi kartı numaralarını saklıyorsanız, bunları bir noktada geri çıkarmanız gerekir, ancak bunları düz metin saklamak istemezsiniz. Bunun yerine, şifrelenmiş sürümü saklayın ve anahtarı olabildiğince güvenli tutun.
Hash işlevleri de veri imzalamak için mükemmeldir. Örneğin, HMAC kullanıyorsanız, bilinen ancak iletilmeyen bir değerle (gizli bir değer) birleştirilmiş verilerin karma değerini alarak bir veri parçasını imzalarsınız. Böylece, düz metni ve HMAC karmasını gönderirsiniz. Daha sonra, alıcı gönderilen verileri bilinen değerde hash eder ve iletilen HMAC ile eşleşip eşleşmediğini kontrol eder. Eğer aynıysa, gizli değeri olmayan bir parti tarafından değiştirilmediğini biliyorsunuz. Bu, HTTP çerçeveleri tarafından güvenli çerez sistemlerinde ve ayrıca verilerde bütünlük güvencesi istediğiniz yerlerde HTTP üzerinden mesaj iletimi için yaygın olarak kullanılır.
Parola karmaları hakkında bir not:
Kriptografik karma işlevlerinin temel bir özelliği, bunların oluşturulmasının çok hızlı ve tersine çevrilmesi çok zor / yavaş olması (pratik olarak imkansız olacak kadar) olmasıdır. Bu parolalarla ilgili bir sorun oluşturur. Depolarsanız sha512(password)
, gökkuşağı masalarına veya kaba kuvvet saldırılarına karşı korunacak bir şey yapmıyorsunuz. Unutmayın, hash fonksiyonu hız için tasarlanmıştır. Bu nedenle, bir saldırganın hash işlevi aracılığıyla bir sözlük çalıştırması ve her sonucu test etmesi önemsizdir.
Bir tuz eklemek, karmaya biraz bilinmeyen veriler eklediğinden önemli olur. Bu nedenle, eşleşen bir şey bulmak yerine md5(foo)
, bilinen tuza eklendiğinde md5(foo.salt)
(yapmak çok daha zor olan) bir şey bulmaları gerekir . Ama yine de hız problemini çözmüyor çünkü tuzu biliyorlarsa bu sadece sözlüğü çalıştırmakla ilgilidir.
Yani, bununla başa çıkmanın yolları var. Popüler bir yönteme anahtar güçlendirme (veya anahtar germe) denir . Temel olarak, bir karma üzerinde birçok kez yinelenirsiniz (genellikle binlerce). Bu iki şey yapar. İlk olarak, karma algoritmasının çalışma süresini önemli ölçüde yavaşlatır. İkincisi, eğer doğru uygulanırsa (giriş ve tuzu her bir iterasyona geri geçirmek), çıkış için entropiyi (kullanılabilir alan) arttırır ve çarpışma olasılığını azaltır. Önemsiz bir uygulama:
var hash = password + salt;
for (var i = 0; i < 5000; i++) {
hash = sha512(hash + password + salt);
}
PBKDF2 , BCrypt gibi daha standart başka uygulamalar da vardır . Ancak bu teknik, güvenlikle ilgili birkaç sistem tarafından kullanılır (PGP, WPA, Apache ve OpenSSL gibi).
Sonuç olarak, hash(password)
yeterince iyi değil. hash(password + salt)
daha iyi, ama yine de yeterince iyi değil ... Parola karmalarınızı üretmek için uzatılmış bir karma mekanizması kullanın ...
Önemsiz esneme üzerine başka bir not
Hiçbir koşulda bir karmanın çıktısını doğrudan karma işlevine geri beslemeyin :
hash = sha512(password + salt);
for (i = 0; i < 1000; i++) {
hash = sha512(hash); // <-- Do NOT do this!
}
Bunun nedeni çarpışmalarla ilgili. Tüm karma işlevlerinin çarpışma olduğunu unutmayın, çünkü olası çıkış alanı (olası çıkışların sayısı) giriş alanından daha küçüktür. Nedenini görmek için neler olduğuna bakalım. Bunu önceden göstermek için,% 0.001'lik bir çarpışma şansı olduğunu varsayalım sha1()
( gerçekte çok daha düşük, ancak gösteri amaçlı).
hash1 = sha1(password + salt);
Şimdi, hash1
% 0.001'lik bir çarpışma olasılığı var. Ama bir sonrakini yaptığımızda hash2 = sha1(hash1);
, tüm çarpışmaları hash1
otomatik olarak çarpışmaları haline gelirhash2
. Şimdi, hash1'in oranı% 0.001'dir ve 2. sha1()
çağrı buna eklenir. Şimdi hash2
% 0.002'lik bir çarpışma olasılığı var. Bu iki kat daha fazla şans! Her yineleme 0.001%
, sonuca bir çarpışma şansı daha ekleyecektir . Böylece, 1000 iterasyonla çarpışma şansı% 0.001'den% 1'e sıçradı. Şimdi, bozulma doğrusaldır ve gerçek olasılıklar çok daha küçüktür, ancak etki aynıdır (tek bir çarpışma şansının tahmini md5
yaklaşık 1 / (2 128 ) veya 1 / (3x10 38'dir)). Bu küçük görünse de , doğum günü saldırısı sayesinde göründüğü kadar küçük değil).
Bunun yerine, her seferinde tuz ve parolayı yeniden ekleyerek, verileri karma işlevine geri eklersiniz. Dolayısıyla, herhangi bir turun çarpışması artık bir sonraki turun çarpışması değildir. Yani:
hash = sha512(password + salt);
for (i = 0; i < 1000; i++) {
hash = sha512(hash + password + salt);
}
Yerel sha512
işlevle aynı çarpışma şansına sahiptir . İstediğin şey bu. Bunun yerine bunu kullanın.