Burada en upvoted cevaplar vurgulamak aksine, sigara birebirlik (yani aynı değere karma birkaç dizeleri vardır) büyük (potansiyel olarak sonsuz) giriş büyüklüğü ve sabit çıkış boyutu arasındaki farktan kaynaklanan bir kriptografik hash fonksiyonunun değil önemli nokta - aslında, bu çarpışmaların mümkün olduğunca nadiren meydana geldiği hash fonksiyonlarını tercih ediyoruz.
Şu işlevi düşünün (soru olarak PHP gösteriminde):
function simple_hash($input) {
return bin2hex(substr(str_pad($input, 16), 0, 16));
}
Bu, dize çok kısaysa bazı boşluklar ekler ve ardından dizenin ilk 16 baytını alır, ardından onu onaltılık olarak kodlar. MD5 hash ile aynı çıktı boyutuna sahiptir (32 onaltılık karakter veya bin2hex bölümünü atlarsak 16 bayt).
print simple_hash("stackoverflow.com");
Bu çıktı:
737461636b6f766572666c6f772e636f6d
Bu işlev aynı zamanda Cody'nin MD5 cevabında vurgulandığı gibi aynı non-non -jectivity özelliğine sahiptir: Herhangi bir boyuttaki dizeleri geçirebiliriz (bilgisayarımıza sığdıkları sürece) ve yalnızca 32 onaltılık basamak çıkarır. Elbette enjekte edilemez.
Ancak bu durumda, aynı hash ile eşleşen bir dizge bulmak önemsizdir (sadece hash'inize uygulayın hex2bin
ve ona sahipsiniz). Orijinal dizeniz 16 uzunluğundaysa (örneğimiz gibi), bu orijinal dizeyi bile elde edeceksiniz. Girdinin uzunluğunun oldukça kısa olduğunu bilseniz bile, MD5 için bu türden hiçbir şey mümkün olmamalıdır (eşleşen bir tane bulana kadar olası tüm girdileri denemekten başka, örneğin kaba kuvvet saldırısı).
Kriptografik bir hash işlevi için önemli varsayımlar şunlardır:
- belirli bir hash üreten herhangi bir dizi bulmak zordur (ön görüntü direnci)
- belirli bir dizeyle aynı karmayı üreten farklı bir dizi bulmak zordur (ikinci ön görüntü direnci)
- aynı hash'e sahip herhangi bir dizi bulmak zordur (çarpışma direnci)
Açıkçası benim simple_hash
işlevim bu koşulların hiçbirini karşılamıyor. (Aslında, girdi alanını "16 baytlık dizelerle" sınırlarsak, o zaman benim işlevim enjekte edici hale gelir ve bu nedenle kanıtlanabilir ikinci ön görüntü dirençli ve çarpışmaya dirençli olur.)
Artık MD5'e karşı çarpışma saldırıları var (örneğin, aynı önekle bile, aynı hash'e sahip, epeyce çalışmayla, ancak çok fazla çalışma imkansız olmayan bir dizi çift üretmek mümkündür), bu nedenle kullanmamalısınız Kritik her şey için MD5. Henüz bir ön görüntü saldırısı yok, ancak saldırılar daha iyi olacak.
Asıl soruyu cevaplamak için:
Ortaya çıkan dizgelerin yeniden izlenmesini imkansız kılan bu işlevlerle ilgili nedir?
MD5'in (ve Merkle-Damgard yapısında inşa edilen diğer hash işlevlerinin) etkin bir şekilde yaptığı şey, anahtar olarak mesaj ve "düz metin" olarak bazı sabit değerler içeren bir şifreleme algoritması uygulamak ve sonuçta elde edilen şifreli metni karma olarak kullanmaktır. (Bundan önce, giriş doldurulur ve bloklar halinde bölünür, bu blokların her biri önceki bloğun çıktısını şifrelemek için kullanılır, ters hesaplamaları önlemek için girişiyle birlikte XORed.)
Modern şifreleme algoritmaları (karma işlevlerde kullanılanlar dahil), hem düz metin hem de şifreli metin verildiğinde (veya düşman bunlardan birini seçtiğinde bile) anahtarı kurtarmayı zorlaştıracak şekilde yapılmıştır. Bunu genellikle, her çıkış bitinin her bir anahtar biti (birkaç kez) ve ayrıca her giriş biti tarafından belirleneceği bir şekilde çok sayıda bit karıştırma işlemi yaparak yaparlar. Bu şekilde, yalnızca tam anahtarı ve girişi veya çıkışı biliyorsanız, içeride olanları kolayca takip edebilirsiniz.
MD5 benzeri karma işlevler ve bir ön görüntü saldırısı için (işleri kolaylaştırmak için tek bloklu bir karma dizeyle), şifreleme işlevinizin yalnızca giriş ve çıkışına sahip olursunuz, ancak anahtarınız yoktur (aradığınız şey budur).