“Çifte karma” bir şifreyi sadece bir kere hash etmekten daha az güvenli midir?


293

Depolamadan önce iki kez bir şifre koymak, yalnızca bir kez şifre koymaktan daha fazla mı yoksa daha az güvenli mi?

Bahsettiğim şey bunu yapmak:

$hashed_password = hash(hash($plaintext_password));

bunun yerine:

$hashed_password = hash($plaintext_password);

Daha az güvenliyse, iyi bir açıklama (veya bir bağlantı) sağlayabilir misiniz?

Ayrıca, kullanılan karma işlevi bir fark yaratır mı? Aynı karma işlevini tekrarlamak yerine md5 ve sha1'i (örneğin) karıştırırsanız herhangi bir fark yaratır mı?

Not 1: "Çifte karma" dediğimde, daha gizli hale getirmek için iki kez bir şifre karmaşasından bahsediyorum. Çarpışmaları çözme tekniğinden bahsetmiyorum .

Not 2: Gerçekten güvenli hale getirmek için rastgele bir tuz eklemem gerektiğini biliyorum. Soru, aynı algoritmayla iki kez karma işleminin karma işlemeye yardımcı olup olmadığı veya zarar vermesidir.


2
Hash(password)ve Hash(Hash(password))eşit derecede güvensizdir. Her ikisi de Anlamsal Güvenlik kavramından yoksundur . Kendisine, çıkış olan rasgele ayırt. Örneğin, MD5("password")bir 5f4dcc3b5aa765d61d8327deb882cf99. Bunun MD5 hash biliyorum passwordve o olduğunu rasgele ayırt. Bunun yerine bir HMAC kullanmalısınız. Onun güvenli bir şekilde ve bir PRF.
jww

Yanıtlar:


267

Parolayı bir kez karıştırmak güvenli değildir

Hayır, çoklu karmalar daha az güvenli değildir; güvenli şifre kullanımının önemli bir parçasıdır.

Karmayı yinelemek, saldırganın aday listelerindeki her parolayı denemesi için gereken süreyi artırır. Bir parola saldırmak için gereken süreyi saatlerden yıllara kolayca artırabilirsiniz.

Basit yineleme yeterli değil

Yalnızca karma çıktıyı girdiye bağlamak güvenlik için yeterli değildir. Yineleme, parolanın entropisini koruyan bir algoritma bağlamında gerçekleşmelidir. Neyse ki, tasarımlarına güvenmek için yeterli incelemeye sahip yayınlanmış birkaç algoritma var.

PBKDF2 gibi iyi bir anahtar türetme algoritması, her karma işlemine şifreyi ekleyerek karma çıktısındaki çarpışmalarla ilgili endişeleri azaltır. PBKDF2 olduğu gibi parola doğrulaması için kullanılabilir. Bcrypt, bir anahtarlama adımı ile anahtar türevini takip eder; bu şekilde, anahtar türetmeyi tersine çevirmenin hızlı bir yolu bulunursa, bir saldırganın hala bilinen düz metin saldırısını tamamlaması gerekir.

Parola nasıl kırılır

Saklanan parolaların çevrimdışı saldırılara karşı korunması gerekir. Parolalar tuzlanmazsa, önceden hesaplanmış bir sözlük saldırısıyla bozulabilir (örneğin, Gökkuşağı Tablosu kullanılarak). Aksi takdirde, saldırganın her parola için bir karma hesaplaması ve depolanan karma ile eşleşip eşleşmediğini görmesi gerekir.

Tüm şifrelerin eşit olması olası değildir. Saldırganlar tüm kısa şifreleri kapsamlı bir şekilde arayabilir, ancak kaba kuvvet başarısı şanslarının her ek karakterle keskin bir şekilde düştüğünü bilirler. Bunun yerine, en olası şifrelerin sıralı bir listesini kullanırlar. "Password123" ile başlarlar ve daha az kullanılan şifrelerle ilerlerler.

Bir saldırgan listesinin 10 milyar adayla uzun olduğunu varsayalım; Ayrıca bir masaüstü sisteminin saniyede 1 milyon karmayı hesaplayabildiğini varsayalım. Yalnızca bir yineleme kullanılırsa, saldırgan tüm listesinin üç saatten az olduğunu test edebilir. Ancak sadece 2000 yineleme kullanılırsa, bu süre neredeyse 8 aya kadar uzar. Örneğin, GPU'larının gücüne dokunabilecek bir programı indirebilen daha karmaşık bir saldırganı yenmek için daha fazla yinelemeye ihtiyacınız vardır.

Ne kadar yeterli?

Kullanılacak yineleme sayısı, güvenlik ve kullanıcı deneyimi arasındaki bir dengedir. Saldırganlar tarafından kullanılabilen özel donanım ucuzdur, ancak yine de saniyede yüz milyonlarca yineleme gerçekleştirebilir. Saldırganın sisteminin performansı, bir dizi yineleme verildiğinde bir parolanın kırılmasının ne kadar süreceğini belirler. Ancak uygulamanızın bu özel donanımı kullanması olası değildir. Kullanıcıları ağırlaştırmadan kaç yineleme yapabileceğiniz , sisteme.

Kimlik doğrulaması sırasında muhtemelen kullanıcıların fazladan bir saniye beklemesine izin verebilirsiniz. Hedef platformunuzun profilini oluşturun ve karşılayabildiğiniz kadar çok yineleme kullanın. Test ettiğim platformlar (bir mobil cihazdaki bir kullanıcı veya bir sunucu platformundaki birçok kullanıcı) 60.000 ila 120.000 yineleme arasında PBKDF2'yi rahatlıkla destekleyebilir veya 12 veya 13 maliyet faktörü ile bcrypt yapabilir .

Daha fazla arka plan

Karma ve tuzun tekrarlamadaki rolü hakkında yetkili bilgiler için PKCS # 5'i okuyun. PBKDF2, parolalardan şifreleme anahtarları oluşturmak için tasarlanmış olsa da, parola kimlik doğrulaması için tek yönlü bir karma olarak iyi çalışır. Her bcrypt yinelemesi bir SHA-2 karma değerinden daha pahalıdır, bu nedenle daha az yineleme kullanabilirsiniz, ancak fikir aynıdır. Bcrypt ayrıca, iyi bilinen bir düz metni şifrelemek için türetilmiş anahtarı kullanarak çoğu PBKDF2 tabanlı çözümün ötesine geçiyor. Ortaya çıkan şifre metni, bazı meta verilerle birlikte "karma" olarak depolanır. Ancak, hiçbir şey PBKDF2 ile aynı şeyi yapmanıza engel olmaz.

İşte bu konuda yazdığım diğer cevaplar:


68
Güvenliği ihlal edilmiş kimlik doğrulama depolarına karşı sözlük saldırılarını önlemeye çalışırken kasıtlı olarak yavaş bir algoritma yapmak kabul edilen bir uygulamadır. Tekniğe "anahtar güçlendirme" veya "anahtar germe" denir. Bkz en.wikipedia.org/wiki/Key_stretching

17
@RoBorg: o nasıl yavaş önemli değil senin uygulamasıdır, ancak nasıl bir saldırganın uygulaması olacak yavaş: karma kendisi yavaş binlerce kez ise, uzun şifreyi kaba zorlamak için olduğu gibi kez bir saldırganın binlerce alacaktır.
orip

5
Muhtemelen 128 bitlik 0 ile 2 ^ 128-1 arasındaki alanda çarpışmalar istersiniz. Karma algoritmanın 2 ^ 128 çıktı alanı mükemmelse, teorik olarak, 2 ^ 128 glif alfabe ile bir ikame şifreniz vardır.
jmucchiello

13
@devin - "benim çözümüm" değil, PKCS # 5 gibi şifre tabanlı şifreleme standartlarına dahil edilmiş ve Robert Morris gibi uzmanlar tarafından önerilen yaygın olarak kabul gören bir uygulamadır. Meşru bir uygulamada, kullanıcıların kimliğini doğrulamak için harcanan zamanın küçük olması son derece ölçeklenebilir. Yalnızca uygulamanızın şifreleri kırması durumunda ölçeklendirilmesi zorlaşır - dolayısıyla öneri. Kesinlikle, bir karma arama alanı olası şifrelerinkinden daha küçüktür, ancak 128 bitlik bir alan bile kaba kuvvetle arama yapmak için çok büyüktür. Savunma tehdidi çevrimdışı sözlük saldırısıdır.
erickson

6
Ben bireysel kullanıcı için rahatsızlık değil, daha çok istekleri yavaşlatmak için CPU yükü güveniyor çünkü, büyük bir kullanıcı tabanı olsaydı sunucuya koymak stres atıfta idi. Bu, daha fazla CPU gücü eklerseniz, o kaba kuvvet saldırganlarının kısıtlamasını azalttığınız anlamına gelir. - Ancak, ölçeklenebilirlik ve yaygın olarak kabul gören uygulama konusunda tamamen haklısınız. Daha önceki yorumlarımda söylediğim neredeyse tüm şeyler hakkında yanılmışım. Üzgünüm :)
DevinB

227

Güvenli olduğunu söyleyenler için genel olarak doğrudurlar . "Çifte" karma (veya bunun bir mantıksal genişletme, bir karma işlevini yineleme) doğru yapılırsa , belirli bir endişe için kesinlikle güvenlidir .

Güvensiz olduğunu söyleyenler için , bu durumda doğrudurlar . Söz konusu gönderilirse kod olan güvensiz. Neden hakkında konuşalım:

$hashed_password1 = md5( md5( plaintext_password ) );
$hashed_password2 = md5( plaintext_password );

Bir hash fonksiyonunun endişe duyduğumuz iki temel özelliği vardır:

  1. Görüntü Öncesi Direnç - Bir karma verildiğinde $h, bir mesaj bulmak zor olmalı $mki$h === hash($m)

  2. İkinci Görüntü Öncesi Direnç - Bir mesaj verildiğinde $m1, farklı bir mesaj bulmak zor olmalı $m2kihash($m1) === hash($m2)

  3. Çarpışma Direnci - mesajların bir çifti bulmak zor olmalı ($m1, $m2)öyle ki hash($m1) === hash($m2)(burada saldırganın hem mesajlar üzerinde kontrole sahip bu İkinci Ön Görüntü direncine benzer olduğunu not, ancak farklı) ...

Şifrelerin saklanması için gerçekten önem verdiğimiz tek şey Görüntü Öncesi Direnç . Diğer ikisi tartışmalı olurdu, çünkü $m1kullanıcının şifresi güvende olmaya çalışıyoruz. Eğer saldırgan zaten varsa, hash'ın koruyacağı hiçbir şey yok ...

REDDİ

Bundan sonraki her şey umursadığımız tek şey Görüntü Öncesi Direnç . Karma fonksiyonlarının diğer iki temel özelliği aynı şekilde dayanamayabilir (ve tipik olarak dayanmaz). Bu nedenle, bu gönderideki sonuçlar yalnızca şifrelerin saklanması için karma işlevler kullanıldığında geçerlidir. Genel olarak uygulanamazlar ...

Başlayalım

Bu tartışma uğruna, kendi hash fonksiyonumuzu icat edelim:

function ourHash($input) {
    $result = 0;
    for ($i = 0; $i < strlen($input); $i++) {
        $result += ord($input[$i]);
    }
    return (string) ($result % 256);
}

Şimdi bu hash fonksiyonunun ne yaptığı oldukça açık olmalıdır. Her bir giriş karakterinin ASCII değerlerini toplar ve daha sonra bu sonucun modulo'unu 256 ile alır.

Öyleyse test edelim:

var_dump(
    ourHash('abc'), // string(2) "38"
    ourHash('def'), // string(2) "47"
    ourHash('hij'), // string(2) "59"
    ourHash('klm')  // string(2) "68"
);

Şimdi, bir işlev etrafında birkaç kez çalıştırırsak ne olacağını görelim:

$tests = array(
    "abc",
    "def",
    "hij",
    "klm",
);

foreach ($tests as $test) {
    $hash = $test;
    for ($i = 0; $i < 100; $i++) {
        $hash = ourHash($hash);
    }
    echo "Hashing $test => $hash\n";
}

Bu çıktı:

Hashing abc => 152
Hashing def => 152
Hashing hij => 155
Hashing klm => 155

Hı, vay. Çarpışmalar yaptık !!! Nedenine bakmaya çalışalım:

Aşağıda, olası her karma çıkışından bir dize hashlama çıktısı verilmiştir:

Hashing 0 => 48
Hashing 1 => 49
Hashing 2 => 50
Hashing 3 => 51
Hashing 4 => 52
Hashing 5 => 53
Hashing 6 => 54
Hashing 7 => 55
Hashing 8 => 56
Hashing 9 => 57
Hashing 10 => 97
Hashing 11 => 98
Hashing 12 => 99
Hashing 13 => 100
Hashing 14 => 101
Hashing 15 => 102
Hashing 16 => 103
Hashing 17 => 104
Hashing 18 => 105
Hashing 19 => 106
Hashing 20 => 98
Hashing 21 => 99
Hashing 22 => 100
Hashing 23 => 101
Hashing 24 => 102
Hashing 25 => 103
Hashing 26 => 104
Hashing 27 => 105
Hashing 28 => 106
Hashing 29 => 107
Hashing 30 => 99
Hashing 31 => 100
Hashing 32 => 101
Hashing 33 => 102
Hashing 34 => 103
Hashing 35 => 104
Hashing 36 => 105
Hashing 37 => 106
Hashing 38 => 107
Hashing 39 => 108
Hashing 40 => 100
Hashing 41 => 101
Hashing 42 => 102
Hashing 43 => 103
Hashing 44 => 104
Hashing 45 => 105
Hashing 46 => 106
Hashing 47 => 107
Hashing 48 => 108
Hashing 49 => 109
Hashing 50 => 101
Hashing 51 => 102
Hashing 52 => 103
Hashing 53 => 104
Hashing 54 => 105
Hashing 55 => 106
Hashing 56 => 107
Hashing 57 => 108
Hashing 58 => 109
Hashing 59 => 110
Hashing 60 => 102
Hashing 61 => 103
Hashing 62 => 104
Hashing 63 => 105
Hashing 64 => 106
Hashing 65 => 107
Hashing 66 => 108
Hashing 67 => 109
Hashing 68 => 110
Hashing 69 => 111
Hashing 70 => 103
Hashing 71 => 104
Hashing 72 => 105
Hashing 73 => 106
Hashing 74 => 107
Hashing 75 => 108
Hashing 76 => 109
Hashing 77 => 110
Hashing 78 => 111
Hashing 79 => 112
Hashing 80 => 104
Hashing 81 => 105
Hashing 82 => 106
Hashing 83 => 107
Hashing 84 => 108
Hashing 85 => 109
Hashing 86 => 110
Hashing 87 => 111
Hashing 88 => 112
Hashing 89 => 113
Hashing 90 => 105
Hashing 91 => 106
Hashing 92 => 107
Hashing 93 => 108
Hashing 94 => 109
Hashing 95 => 110
Hashing 96 => 111
Hashing 97 => 112
Hashing 98 => 113
Hashing 99 => 114
Hashing 100 => 145
Hashing 101 => 146
Hashing 102 => 147
Hashing 103 => 148
Hashing 104 => 149
Hashing 105 => 150
Hashing 106 => 151
Hashing 107 => 152
Hashing 108 => 153
Hashing 109 => 154
Hashing 110 => 146
Hashing 111 => 147
Hashing 112 => 148
Hashing 113 => 149
Hashing 114 => 150
Hashing 115 => 151
Hashing 116 => 152
Hashing 117 => 153
Hashing 118 => 154
Hashing 119 => 155
Hashing 120 => 147
Hashing 121 => 148
Hashing 122 => 149
Hashing 123 => 150
Hashing 124 => 151
Hashing 125 => 152
Hashing 126 => 153
Hashing 127 => 154
Hashing 128 => 155
Hashing 129 => 156
Hashing 130 => 148
Hashing 131 => 149
Hashing 132 => 150
Hashing 133 => 151
Hashing 134 => 152
Hashing 135 => 153
Hashing 136 => 154
Hashing 137 => 155
Hashing 138 => 156
Hashing 139 => 157
Hashing 140 => 149
Hashing 141 => 150
Hashing 142 => 151
Hashing 143 => 152
Hashing 144 => 153
Hashing 145 => 154
Hashing 146 => 155
Hashing 147 => 156
Hashing 148 => 157
Hashing 149 => 158
Hashing 150 => 150
Hashing 151 => 151
Hashing 152 => 152
Hashing 153 => 153
Hashing 154 => 154
Hashing 155 => 155
Hashing 156 => 156
Hashing 157 => 157
Hashing 158 => 158
Hashing 159 => 159
Hashing 160 => 151
Hashing 161 => 152
Hashing 162 => 153
Hashing 163 => 154
Hashing 164 => 155
Hashing 165 => 156
Hashing 166 => 157
Hashing 167 => 158
Hashing 168 => 159
Hashing 169 => 160
Hashing 170 => 152
Hashing 171 => 153
Hashing 172 => 154
Hashing 173 => 155
Hashing 174 => 156
Hashing 175 => 157
Hashing 176 => 158
Hashing 177 => 159
Hashing 178 => 160
Hashing 179 => 161
Hashing 180 => 153
Hashing 181 => 154
Hashing 182 => 155
Hashing 183 => 156
Hashing 184 => 157
Hashing 185 => 158
Hashing 186 => 159
Hashing 187 => 160
Hashing 188 => 161
Hashing 189 => 162
Hashing 190 => 154
Hashing 191 => 155
Hashing 192 => 156
Hashing 193 => 157
Hashing 194 => 158
Hashing 195 => 159
Hashing 196 => 160
Hashing 197 => 161
Hashing 198 => 162
Hashing 199 => 163
Hashing 200 => 146
Hashing 201 => 147
Hashing 202 => 148
Hashing 203 => 149
Hashing 204 => 150
Hashing 205 => 151
Hashing 206 => 152
Hashing 207 => 153
Hashing 208 => 154
Hashing 209 => 155
Hashing 210 => 147
Hashing 211 => 148
Hashing 212 => 149
Hashing 213 => 150
Hashing 214 => 151
Hashing 215 => 152
Hashing 216 => 153
Hashing 217 => 154
Hashing 218 => 155
Hashing 219 => 156
Hashing 220 => 148
Hashing 221 => 149
Hashing 222 => 150
Hashing 223 => 151
Hashing 224 => 152
Hashing 225 => 153
Hashing 226 => 154
Hashing 227 => 155
Hashing 228 => 156
Hashing 229 => 157
Hashing 230 => 149
Hashing 231 => 150
Hashing 232 => 151
Hashing 233 => 152
Hashing 234 => 153
Hashing 235 => 154
Hashing 236 => 155
Hashing 237 => 156
Hashing 238 => 157
Hashing 239 => 158
Hashing 240 => 150
Hashing 241 => 151
Hashing 242 => 152
Hashing 243 => 153
Hashing 244 => 154
Hashing 245 => 155
Hashing 246 => 156
Hashing 247 => 157
Hashing 248 => 158
Hashing 249 => 159
Hashing 250 => 151
Hashing 251 => 152
Hashing 252 => 153
Hashing 253 => 154
Hashing 254 => 155
Hashing 255 => 156

Daha yüksek sayılara olan eğilime dikkat edin. Bu bizim ölümümüz oldu. Karmayı 4 kez çalıştırmak ($ ​​hash = ourHash ($ hash) `, her öğe için) bize rüzgar verir:

Hashing 0 => 153
Hashing 1 => 154
Hashing 2 => 155
Hashing 3 => 156
Hashing 4 => 157
Hashing 5 => 158
Hashing 6 => 150
Hashing 7 => 151
Hashing 8 => 152
Hashing 9 => 153
Hashing 10 => 157
Hashing 11 => 158
Hashing 12 => 150
Hashing 13 => 154
Hashing 14 => 155
Hashing 15 => 156
Hashing 16 => 157
Hashing 17 => 158
Hashing 18 => 150
Hashing 19 => 151
Hashing 20 => 158
Hashing 21 => 150
Hashing 22 => 154
Hashing 23 => 155
Hashing 24 => 156
Hashing 25 => 157
Hashing 26 => 158
Hashing 27 => 150
Hashing 28 => 151
Hashing 29 => 152
Hashing 30 => 150
Hashing 31 => 154
Hashing 32 => 155
Hashing 33 => 156
Hashing 34 => 157
Hashing 35 => 158
Hashing 36 => 150
Hashing 37 => 151
Hashing 38 => 152
Hashing 39 => 153
Hashing 40 => 154
Hashing 41 => 155
Hashing 42 => 156
Hashing 43 => 157
Hashing 44 => 158
Hashing 45 => 150
Hashing 46 => 151
Hashing 47 => 152
Hashing 48 => 153
Hashing 49 => 154
Hashing 50 => 155
Hashing 51 => 156
Hashing 52 => 157
Hashing 53 => 158
Hashing 54 => 150
Hashing 55 => 151
Hashing 56 => 152
Hashing 57 => 153
Hashing 58 => 154
Hashing 59 => 155
Hashing 60 => 156
Hashing 61 => 157
Hashing 62 => 158
Hashing 63 => 150
Hashing 64 => 151
Hashing 65 => 152
Hashing 66 => 153
Hashing 67 => 154
Hashing 68 => 155
Hashing 69 => 156
Hashing 70 => 157
Hashing 71 => 158
Hashing 72 => 150
Hashing 73 => 151
Hashing 74 => 152
Hashing 75 => 153
Hashing 76 => 154
Hashing 77 => 155
Hashing 78 => 156
Hashing 79 => 157
Hashing 80 => 158
Hashing 81 => 150
Hashing 82 => 151
Hashing 83 => 152
Hashing 84 => 153
Hashing 85 => 154
Hashing 86 => 155
Hashing 87 => 156
Hashing 88 => 157
Hashing 89 => 158
Hashing 90 => 150
Hashing 91 => 151
Hashing 92 => 152
Hashing 93 => 153
Hashing 94 => 154
Hashing 95 => 155
Hashing 96 => 156
Hashing 97 => 157
Hashing 98 => 158
Hashing 99 => 150
Hashing 100 => 154
Hashing 101 => 155
Hashing 102 => 156
Hashing 103 => 157
Hashing 104 => 158
Hashing 105 => 150
Hashing 106 => 151
Hashing 107 => 152
Hashing 108 => 153
Hashing 109 => 154
Hashing 110 => 155
Hashing 111 => 156
Hashing 112 => 157
Hashing 113 => 158
Hashing 114 => 150
Hashing 115 => 151
Hashing 116 => 152
Hashing 117 => 153
Hashing 118 => 154
Hashing 119 => 155
Hashing 120 => 156
Hashing 121 => 157
Hashing 122 => 158
Hashing 123 => 150
Hashing 124 => 151
Hashing 125 => 152
Hashing 126 => 153
Hashing 127 => 154
Hashing 128 => 155
Hashing 129 => 156
Hashing 130 => 157
Hashing 131 => 158
Hashing 132 => 150
Hashing 133 => 151
Hashing 134 => 152
Hashing 135 => 153
Hashing 136 => 154
Hashing 137 => 155
Hashing 138 => 156
Hashing 139 => 157
Hashing 140 => 158
Hashing 141 => 150
Hashing 142 => 151
Hashing 143 => 152
Hashing 144 => 153
Hashing 145 => 154
Hashing 146 => 155
Hashing 147 => 156
Hashing 148 => 157
Hashing 149 => 158
Hashing 150 => 150
Hashing 151 => 151
Hashing 152 => 152
Hashing 153 => 153
Hashing 154 => 154
Hashing 155 => 155
Hashing 156 => 156
Hashing 157 => 157
Hashing 158 => 158
Hashing 159 => 159
Hashing 160 => 151
Hashing 161 => 152
Hashing 162 => 153
Hashing 163 => 154
Hashing 164 => 155
Hashing 165 => 156
Hashing 166 => 157
Hashing 167 => 158
Hashing 168 => 159
Hashing 169 => 151
Hashing 170 => 152
Hashing 171 => 153
Hashing 172 => 154
Hashing 173 => 155
Hashing 174 => 156
Hashing 175 => 157
Hashing 176 => 158
Hashing 177 => 159
Hashing 178 => 151
Hashing 179 => 152
Hashing 180 => 153
Hashing 181 => 154
Hashing 182 => 155
Hashing 183 => 156
Hashing 184 => 157
Hashing 185 => 158
Hashing 186 => 159
Hashing 187 => 151
Hashing 188 => 152
Hashing 189 => 153
Hashing 190 => 154
Hashing 191 => 155
Hashing 192 => 156
Hashing 193 => 157
Hashing 194 => 158
Hashing 195 => 159
Hashing 196 => 151
Hashing 197 => 152
Hashing 198 => 153
Hashing 199 => 154
Hashing 200 => 155
Hashing 201 => 156
Hashing 202 => 157
Hashing 203 => 158
Hashing 204 => 150
Hashing 205 => 151
Hashing 206 => 152
Hashing 207 => 153
Hashing 208 => 154
Hashing 209 => 155
Hashing 210 => 156
Hashing 211 => 157
Hashing 212 => 158
Hashing 213 => 150
Hashing 214 => 151
Hashing 215 => 152
Hashing 216 => 153
Hashing 217 => 154
Hashing 218 => 155
Hashing 219 => 156
Hashing 220 => 157
Hashing 221 => 158
Hashing 222 => 150
Hashing 223 => 151
Hashing 224 => 152
Hashing 225 => 153
Hashing 226 => 154
Hashing 227 => 155
Hashing 228 => 156
Hashing 229 => 157
Hashing 230 => 158
Hashing 231 => 150
Hashing 232 => 151
Hashing 233 => 152
Hashing 234 => 153
Hashing 235 => 154
Hashing 236 => 155
Hashing 237 => 156
Hashing 238 => 157
Hashing 239 => 158
Hashing 240 => 150
Hashing 241 => 151
Hashing 242 => 152
Hashing 243 => 153
Hashing 244 => 154
Hashing 245 => 155
Hashing 246 => 156
Hashing 247 => 157
Hashing 248 => 158
Hashing 249 => 159
Hashing 250 => 151
Hashing 251 => 152
Hashing 252 => 153
Hashing 253 => 154
Hashing 254 => 155
Hashing 255 => 156

Biz de bu ... 8 değerlerine kendimizi dar ettik kötü ... Bizim asıl işlevi eşlenen S(∞)üzerine S(256). Yani bir Hedef Fonksiyon eşlemesi $inputoluşturduk $output.

Bir Amaç fonksiyonumuz olduğu için, girdinin herhangi bir alt kümesinin eşleşmesinin çarpışma olmayacağını garanti etmiyoruz (aslında pratikte olacak).

Burada olan buydu! İşlevimiz kötüydü, ama bu yüzden işe yaramadı (bu yüzden çok hızlı ve tamamen çalıştı).

Aynı şey olur MD5. Harita S(∞)üzerinde S(2^128). Koşmanın TarafsızMD5(S(output)) olacağının garantisi olmadığından olmadığı için, çarpışma olmayacağı anlamına gelir.

TL / DR Bölümü

Bu nedenle, çıktıyı md5doğrudan geri beslemek çarpışmalara neden olabileceğinden, her yineleme çarpışma olasılığını artıracaktır. Bununla birlikte, bu doğrusal bir artıştır, yani sonuç kümesi 2^128azaltılırken, kritik bir kusur olacak kadar hızlı bir şekilde azaltılmaz.

Yani,

$output = md5($input); // 2^128 possibilities
$output = md5($output); // < 2^128 possibilities
$output = md5($output); // < 2^128 possibilities
$output = md5($output); // < 2^128 possibilities
$output = md5($output); // < 2^128 possibilities

Ne kadar çok tekrar ederseniz, azalma o kadar artar.

Çözüm

Neyse ki bizim için, bunu düzeltmenin önemsiz bir yolu var: Bir şeyi daha fazla iterasyona geri besleyin :

$output = md5($input); // 2^128 possibilities
$output = md5($input . $output); // 2^128 possibilities
$output = md5($input . $output); // 2^128 possibilities
$output = md5($input . $output); // 2^128 possibilities
$output = md5($input . $output); // 2^128 possibilities    

Diğer yinelemelerin, her bir ayrı değer için 2 ^ 128 olmadığını unutmayın $input. Bu $input, hala çizgide çarpışan değerler üretebileceğimiz anlamına gelir (ve dolayısıyla 2^128olası çıktılardan çok daha azına yerleşir veya rezonans eder ). Ancak genel durum$input hala tek bir tur olduğu kadar güçlü.

Bekle, değil mi? Bunu ourHash()fonksiyonumuzla test edelim . Geçme $hash = ourHash($input . $hash);100 tekrarlamalar için:

Hashing 0 => 201
Hashing 1 => 212
Hashing 2 => 199
Hashing 3 => 201
Hashing 4 => 203
Hashing 5 => 205
Hashing 6 => 207
Hashing 7 => 209
Hashing 8 => 211
Hashing 9 => 204
Hashing 10 => 251
Hashing 11 => 147
Hashing 12 => 251
Hashing 13 => 148
Hashing 14 => 253
Hashing 15 => 0
Hashing 16 => 1
Hashing 17 => 2
Hashing 18 => 161
Hashing 19 => 163
Hashing 20 => 147
Hashing 21 => 251
Hashing 22 => 148
Hashing 23 => 253
Hashing 24 => 0
Hashing 25 => 1
Hashing 26 => 2
Hashing 27 => 161
Hashing 28 => 163
Hashing 29 => 8
Hashing 30 => 251
Hashing 31 => 148
Hashing 32 => 253
Hashing 33 => 0
Hashing 34 => 1
Hashing 35 => 2
Hashing 36 => 161
Hashing 37 => 163
Hashing 38 => 8
Hashing 39 => 4
Hashing 40 => 148
Hashing 41 => 253
Hashing 42 => 0
Hashing 43 => 1
Hashing 44 => 2
Hashing 45 => 161
Hashing 46 => 163
Hashing 47 => 8
Hashing 48 => 4
Hashing 49 => 9
Hashing 50 => 253
Hashing 51 => 0
Hashing 52 => 1
Hashing 53 => 2
Hashing 54 => 161
Hashing 55 => 163
Hashing 56 => 8
Hashing 57 => 4
Hashing 58 => 9
Hashing 59 => 11
Hashing 60 => 0
Hashing 61 => 1
Hashing 62 => 2
Hashing 63 => 161
Hashing 64 => 163
Hashing 65 => 8
Hashing 66 => 4
Hashing 67 => 9
Hashing 68 => 11
Hashing 69 => 4
Hashing 70 => 1
Hashing 71 => 2
Hashing 72 => 161
Hashing 73 => 163
Hashing 74 => 8
Hashing 75 => 4
Hashing 76 => 9
Hashing 77 => 11
Hashing 78 => 4
Hashing 79 => 3
Hashing 80 => 2
Hashing 81 => 161
Hashing 82 => 163
Hashing 83 => 8
Hashing 84 => 4
Hashing 85 => 9
Hashing 86 => 11
Hashing 87 => 4
Hashing 88 => 3
Hashing 89 => 17
Hashing 90 => 161
Hashing 91 => 163
Hashing 92 => 8
Hashing 93 => 4
Hashing 94 => 9
Hashing 95 => 11
Hashing 96 => 4
Hashing 97 => 3
Hashing 98 => 17
Hashing 99 => 13
Hashing 100 => 246
Hashing 101 => 248
Hashing 102 => 49
Hashing 103 => 44
Hashing 104 => 255
Hashing 105 => 198
Hashing 106 => 43
Hashing 107 => 51
Hashing 108 => 202
Hashing 109 => 2
Hashing 110 => 248
Hashing 111 => 49
Hashing 112 => 44
Hashing 113 => 255
Hashing 114 => 198
Hashing 115 => 43
Hashing 116 => 51
Hashing 117 => 202
Hashing 118 => 2
Hashing 119 => 51
Hashing 120 => 49
Hashing 121 => 44
Hashing 122 => 255
Hashing 123 => 198
Hashing 124 => 43
Hashing 125 => 51
Hashing 126 => 202
Hashing 127 => 2
Hashing 128 => 51
Hashing 129 => 53
Hashing 130 => 44
Hashing 131 => 255
Hashing 132 => 198
Hashing 133 => 43
Hashing 134 => 51
Hashing 135 => 202
Hashing 136 => 2
Hashing 137 => 51
Hashing 138 => 53
Hashing 139 => 55
Hashing 140 => 255
Hashing 141 => 198
Hashing 142 => 43
Hashing 143 => 51
Hashing 144 => 202
Hashing 145 => 2
Hashing 146 => 51
Hashing 147 => 53
Hashing 148 => 55
Hashing 149 => 58
Hashing 150 => 198
Hashing 151 => 43
Hashing 152 => 51
Hashing 153 => 202
Hashing 154 => 2
Hashing 155 => 51
Hashing 156 => 53
Hashing 157 => 55
Hashing 158 => 58
Hashing 159 => 0
Hashing 160 => 43
Hashing 161 => 51
Hashing 162 => 202
Hashing 163 => 2
Hashing 164 => 51
Hashing 165 => 53
Hashing 166 => 55
Hashing 167 => 58
Hashing 168 => 0
Hashing 169 => 209
Hashing 170 => 51
Hashing 171 => 202
Hashing 172 => 2
Hashing 173 => 51
Hashing 174 => 53
Hashing 175 => 55
Hashing 176 => 58
Hashing 177 => 0
Hashing 178 => 209
Hashing 179 => 216
Hashing 180 => 202
Hashing 181 => 2
Hashing 182 => 51
Hashing 183 => 53
Hashing 184 => 55
Hashing 185 => 58
Hashing 186 => 0
Hashing 187 => 209
Hashing 188 => 216
Hashing 189 => 219
Hashing 190 => 2
Hashing 191 => 51
Hashing 192 => 53
Hashing 193 => 55
Hashing 194 => 58
Hashing 195 => 0
Hashing 196 => 209
Hashing 197 => 216
Hashing 198 => 219
Hashing 199 => 220
Hashing 200 => 248
Hashing 201 => 49
Hashing 202 => 44
Hashing 203 => 255
Hashing 204 => 198
Hashing 205 => 43
Hashing 206 => 51
Hashing 207 => 202
Hashing 208 => 2
Hashing 209 => 51
Hashing 210 => 49
Hashing 211 => 44
Hashing 212 => 255
Hashing 213 => 198
Hashing 214 => 43
Hashing 215 => 51
Hashing 216 => 202
Hashing 217 => 2
Hashing 218 => 51
Hashing 219 => 53
Hashing 220 => 44
Hashing 221 => 255
Hashing 222 => 198
Hashing 223 => 43
Hashing 224 => 51
Hashing 225 => 202
Hashing 226 => 2
Hashing 227 => 51
Hashing 228 => 53
Hashing 229 => 55
Hashing 230 => 255
Hashing 231 => 198
Hashing 232 => 43
Hashing 233 => 51
Hashing 234 => 202
Hashing 235 => 2
Hashing 236 => 51
Hashing 237 => 53
Hashing 238 => 55
Hashing 239 => 58
Hashing 240 => 198
Hashing 241 => 43
Hashing 242 => 51
Hashing 243 => 202
Hashing 244 => 2
Hashing 245 => 51
Hashing 246 => 53
Hashing 247 => 55
Hashing 248 => 58
Hashing 249 => 0
Hashing 250 => 43
Hashing 251 => 51
Hashing 252 => 202
Hashing 253 => 2
Hashing 254 => 51
Hashing 255 => 53

Orada bir kaba desen hala orada, ama not hayır olduğunu daha (zaten oldukça zayıf) bizim temel işlevi daha desen.

Ancak dikkat edin 0ve3 , tek seferde olmasalar bile, çarpışmalar oldu. Bu, daha önce söylediğim bir uygulama (çarpışma direncinin tüm girdilerin seti için aynı kalması, ancak altta yatan algoritmada kusurlar nedeniyle belirli çarpışma yolları açılabilir).

TL / DR Bölümü

Girdileri her bir yinelemeye geri besleyerek, önceki yinelemede meydana gelebilecek çarpışmaları etkin bir şekilde koparırız.

Bu nedenle md5($input . md5($input));( en azından teorik olarak) kadar güçlü olmalıdır md5($input).

Bu önemli mi?

Evet. Bu, RFC 2898'de PBKDF2'nin PBKDF1'in yerini almasının nedenlerinden biridir . İkisinin iç döngülerini düşünün ::

PBKDF1:

T_1 = Hash (P || S) ,
T_2 = Hash (T_1) ,
...
T_c = Hash (T_{c-1}) 

cYineleme sayısı nerede , PParola veS tuz

PBKDF2:

U_1 = PRF (P, S || INT (i)) ,
U_2 = PRF (P, U_1) ,
...
U_c = PRF (P, U_{c-1})

PRF gerçekten sadece bir HMAC. Ancak buradaki amaçlarımız için, diyelim ki PRF(P, S) = Hash(P || S)(yani, 2 girdinin PRF'si, ikisi birlikte bir araya getirilmiş karma ile aynı, kabaca konuşur). Çok değil , ama bizim amacımız için öyle.

Böylece PBKDF2, temel Hashfonksiyonun PBKDF1'in çarpmadığı çarpışma direncini korur .

Hepsini Birleştirin:

Bir hash yinelemenin güvenli yollarını biliyoruz. Aslında:

$hash = $input;
$i = 10000;
do {
   $hash = hash($input . $hash);
} while ($i-- > 0);

Genellikle güvenlidir.

Şimdi, neden hash etmek istediğimize girmek için, entropi hareketini analiz edelim.

Bir karma sonsuz seti alır: S(∞)ve daha küçük, tutarlı boyutlu bir set üretir S(n). Bir sonraki adım (giriş varsayarak geri geçirilir) eşler S(∞)üzerine S(n)yine:

S(∞) -> S(n)
S(∞) -> S(n)
S(∞) -> S(n)
S(∞) -> S(n)
S(∞) -> S(n)
S(∞) -> S(n)

Nihai çıktının birincisi ile aynı miktarda entropiye sahip olduğuna dikkat edin . Yineleme "daha karanlık" yapmaz . Entropi aynıdır. Öngörülemeyen sihirli bir kaynak yok (Rastgele Bir İşlev değil, bir Rastgele Rastgele İşlev).

Ancak yinelemenin bir kazancı vardır. Karma sürecini yapay olarak yavaşlatır. Bu yüzden yineleme iyi bir fikir olabilir. Aslında, en modern şifre hash algoritmalarının temel prensibi (tekrar tekrar bir şey yapmanın onu yavaşlatması).

Yavaş iyidir, çünkü birincil güvenlik tehdidi ile savaşır: kaba kuvvet. Karma algoritmamızı ne kadar yavaş yaparsak, saldırganların bizden çalınan parola karmalarına saldırmak için daha fazla çalışması gerekir. Ve bu iyi bir şey !!!


1
$output = md5($output); // < 2^128 possibilities--- gerçekten katı mı <, yoksa <=?
zerkms

2
@zerkms: Kesinlikle hiçbir şey değil. md5()Gerçekten emin olmak için altta yatan fonksiyonun ( bu örnekte) bazı çok spesifik ayrıntılarını bilmemiz gerekir . Ama genel olarak öyle olacak <ve olmayacak <=... Unutmayın, mümkün $outputolan herkes için setin büyüklüğünden bahsediyoruz $inputs. Biz bile var ise bir çarpışma öyle olacak <, dolayısıyla <daha iyi generalizer olduğunu.
ircmaxell

2
@ TomášFejfar Bence soru genel olarak çarpışmalar değil, katı çıktı setindeki çarpışmalar (her biri tam olarak 128 bit genişliğinde). Bu Injective olabilir , ama bildiğim kadarıyla jenerik bir kanıt mümkün değildir (sadece belirli bir algoritma için çarpışma örneğinin bir kanıtı). 128 bit (ve aksi takdirde karma) ise girdiyi döndüren karma işlevini düşünün. Genel olarak bu amaç olurdu, ancak çıktısını beslediğinde her zaman
sakıncalı


6
Dan & ircmaxell arasındaki bu tartışmanın nasıl bittiğini kontrol etmek zorunda kalmadan zaman kazanmak isteyenler için iyi sonuç verdi : Dan ircmaxell ile hemfikir.
jeromej

51

Evet, yeniden sağlama, arama alanını azaltır, ancak hayır, önemli değil - etkili azaltma önemsizdir.

Yeniden karıştırma, kaba kuvvet için gereken süreyi arttırır, ancak bunu sadece iki kez yapmak da yetersizdir.

Gerçekten istediğiniz şey, şifrenin tuz ve iterasyonlarla güvenli bir karma kullanmanın kanıtlanmış bir yöntemi olan PBKDF2 ile hash etmektir . Bu SO yanıtına göz atın .

DÜZENLE : Neredeyse unuttum - MD5 KULLANMAYIN !!!! SHA-2 ailesi (SHA-256, SHA-384 ve SHA-512) gibi modern bir şifreleme karması kullanın.


2
@DFTR - kabul etti. bcrypt veya scrypt daha iyi seçeneklerdir.
orip

Bunları da kullanmayın (SHA-2 ailesi) artık kolayca kırılabilirler , kanıt için crackstation.net'e bakın. Herhangi bir şey anahtar türetme işlevi (KDF) tabanlı kriptografik sağlama işlevleri olan scrypt veya PBKDF2 kullanırsa.
theodore

3
2016 yılında, Argon2 ve scrypt herkesin kullanmak için çaba göstermesi gerekenler
Silkfire

10

Evet - dizeyle eşleşen olası dizelerin sayısını azaltır.

Daha önce de belirttiğiniz gibi, tuzlanmış karmalar çok daha iyidir.

Burada bir makale: http://websecurity.ro/blog/2007/11/02/md5md5-vs-md5/ , bunun neden eşdeğer olduğunu kanıtlamaya çalışır, ancak mantığından emin değilim. Kısmen, md5'i (md5 (metin)) analiz etmek için mevcut bir yazılım olmadığını varsayarlar, ancak açıkçası gökkuşağı tablolarını üretmek oldukça önemsizdir.

Hala cevabımla md5 (md5 (metin)) tür karmaların md5 (metin) karmalarından daha az sayıda olduğunu, çarpışma olasılığını artırarak (hala olası bir olasılığa rağmen) ve arama alanını azalttığımı düşünüyorum.


5

Çoğu yanıt, kriptografi veya güvenlik konusunda arka planı olmayan kişilerdir. Ve yanılıyorlar. Mümkünse kayıt başına benzersiz bir tuz kullanın. MD5 / SHA / vb çok hızlı, ne istediğinizi tersidir. PBKDF2 ve bcrypt daha yavaştır (hangisi iyidir) ancak ASIC'ler / FPGA / GPU'lar (günümüzde çok iyi anlaşılabilir) ile yenilebilir. Bu yüzden bir bellek-zor algoritması gereklidir: scrypt girin .

İşte tuzlar ve hız hakkında bir layman açıklaması (ancak bellek-sert algoritmalar hakkında değil).


4

Buna pratik bir açıdan bakıyorum. Bilgisayar korsanı neyin peşinde? Neden, hash işlevine konduğunda istenen karmayı üreten karakterlerin kombinasyonu.

Sadece son karmayı kurtarıyorsunuz, bu nedenle hacker sadece bir karmayı bruteforce etmek zorunda. Her bruteforce adımı ile istenen karma için kabaca aynı olasılıklara sahip olduğunuzu varsayarsak, karma sayısı önemsizdir. Bir milyon karma yineleme yapabilirsiniz ve güvenliği bir bit arttırmaz veya azaltmaz, çünkü hattın sonunda hala kırılacak sadece bir karma vardır ve onu kırma olasılıkları herhangi bir karma ile aynıdır.

Belki de önceki posterler girdinin ilgili olduğunu düşünüyor; değil. Karma fonksiyonuna koyduğunuz her şey istenen karmayı ürettiği sürece, size doğru girişi veya yanlış girişi sağlayacaktır.

Şimdi, gökkuşağı masaları başka bir hikaye. Gökkuşağı tablosu yalnızca ham parolalar içerdiğinden, her karmanın her karmasını içeren bir gökkuşağı tablosu çok büyük olacağından, iki kez karma yapmak iyi bir güvenlik önlemi olabilir.

Tabii ki, sadece OP'nin verdiği örneği ele alıyorum, sadece düz metinli bir parola. Kullanıcı adını veya bir tuzu karma içine eklerseniz, bu farklı bir hikaye; iki kez karma yapmak tamamen gereksizdir, çünkü gökkuşağı masası pratik olmak ve doğru hash'ı içermek için çok büyük olacaktır.

Her neyse, burada bir güvenlik uzmanı değil, ama benim deneyimlerimden anladım.


Bu cevap her açıdan yanlıştır. 1. Bir sonraki-son karmayı bilmek saldırgan için bir değer sağlamaz, çünkü yinelenen bir karmaya giriş , daha sonra birçok kez (bir kez değil) hash edilen paroladır . 2. Giriş alanı şifreler, çıkış alanı karma şifrelerdir. Uzay tipik şifreleri çıkış alanından çok daha küçüktür. 3. Tuzsuz çift karma parolalar için gökkuşağı tabloları, tuzsuz tek karma parolalar için gökkuşağı tablolarından daha büyük değildir. 4. Kullanıcı adları düşük entropi, iyi bir tuz rastgele. 5. Tuzlama yinelemenin yerini almaz. Her ikisine de ihtiyacınız var.
Clement Cherlin

3

Okuduğum kadarıyla, şifreyi yüzlerce veya binlerce kez yeniden hashlamanız tavsiye edilebilir.

Fikir şu ki, şifreyi kodlamak daha fazla zaman alabilirse, bir saldırganın şifreyi kırmak için birçok tahminde bulunması daha fazla iştir. Bu, yeniden şifrelemenin avantajı gibi görünüyor - daha kriptografik olarak daha güvenli değil, ancak bir sözlük saldırısı oluşturmak daha uzun sürüyor.

Tabii ki bilgisayarlar her zaman daha hızlı hale gelir, bu nedenle bu avantaj zamanla azalır (veya yinelemeleri artırmanızı gerektirir).


Ben de başka bir yorumda bu söz, ancak en.wikipedia.org/wiki/Key_stretching

2

Şahsen birden fazla karma ile uğraşmazdım, ancak aynı parolaya sahip iki kullanıcının aynı karma ile bitmeyeceği için UserName (veya başka bir User ID alanı) ve parolayı da karma yaptığınızdan emin olurum . Ayrıca muhtemelen iyi bir ölçü için giriş dizesine başka bir sabit dize atmak.

$hashed_password = md5( "xxx" + "|" + user_name + "|" + plaintext_password);

13
Aslında, her kullanıcı için rastgele değil, sabit olmayan bir dize olmalıdır.
Kertenkele Bill

7
Kullanıcı adını önerildiği gibi atarsanız, sürekli bir sır çalışır (ve çalışmak daha kolaydır). Bu aslında rastgele bir kullanıcıya özgü anahtar üretir.
SquareCog

4
Sabit bir gizli tuz, belirsizlikten kaynaklanan güvenliktir. "Gizli", "xxx" + kullanıcı adı + şifre kullandığınızı gösterirse, bir saldırganın ona karşı bir saldırı başlatmak için tablolarınızdaki verilere bile ihtiyacı yoktur.
Bill the Lizard

8
Bunun gizlilik yoluyla güvenlik olduğunu düşünmüyorum. Bir tuz kullanmanın nedeni, aynı anda birden fazla md5 karmasına karşı bir gökkuşağı tablosu hesaplayamamanızdır. "Xxx" + şifresi (aynı tuz) için bir tane oluşturmak bir kez olur. "Xxx" + kullanıcı adı + şifre için bir tablo oluşturmak kaba zorlamadan daha kötüdür.
FryGuy

5
@ Kertenkele: "saldırı, belirli bir kullanıcı adına saldırmak için bir sözlük oluşturmaya indirgenir" sadece bir kaba kuvvet saldırısıdır (aslında daha da kötüsü, çünkü tüm hashleri ​​hesaplamanın yanı sıra bunları saklamanız gerekir), böylece tuz çalışır bu durumda mükemmel.
Kornel

2

Karma algoritmasını kullandığınızı varsayalım: rot13 hesapla, ilk 10 karakteri al. Bunu iki kez (hatta 2000 kez) yaparsanız, daha hızlı, ancak aynı sonucu veren bir işlev yapmak mümkündür (sadece ilk 10 karakteri alın).

Benzer şekilde, tekrarlanan bir hash fonksiyonu ile aynı çıktıyı veren daha hızlı bir fonksiyon yapmak mümkün olabilir. Bu nedenle hash fonksiyonu seçiminiz çok önemlidir: rot13 örneğinde olduğu gibi tekrarlanan hashın güvenliği artıracağı söylenmez. Algoritmanın özyinelemeli kullanım için tasarlandığını söyleyen bir araştırma yoksa, size ek koruma sağlamayacağını varsaymak daha güvenlidir.

Bununla birlikte: En basit karma işlevler dışındaki herkes için, daha hızlı işlevleri hesaplamak için büyük olasılıkla şifreleme uzmanları alacaktır, bu nedenle şifreleme uzmanlarına erişimi olmayan saldırganlara karşı korunuyorsanız, pratikte tekrarlanan bir karma işlevi kullanmak muhtemelen daha güvenlidir. .


1

Genel olarak, bir şeyi iki katına çıkarmak veya çift şifrelemek için ek güvenlik sağlamaz. Eğer karmayı bir kez kırabilirsen, tekrar kırabilirsin. Ancak bunu yapmak genellikle güvenliğe zarar vermez.

MD5 kullanma örneğinizde, muhtemelen bildiğiniz gibi bazı çakışma sorunları var. "Çifte Hashing" buna karşı korumaya gerçekten yardımcı olmaz, çünkü aynı çarpışmalar yine aynı ilk hash ile sonuçlanır, bu da ikinci hash almak için MD5'i tekrar yapabilirsiniz.

Bu, "ters MD5 veritabanları" gibi sözlük saldırılarına karşı koruma sağlar, ancak tuzlama da öyle.

Teğet olarak, bir şeyi çift şifrelemek ek bir güvenlik sağlamaz, çünkü yaptığı tek şey aslında kullanılan iki anahtarın birleşimi olan farklı bir anahtarla sonuçlanır. Bu nedenle, "anahtarı" bulma çabası iki katına çıkmaz, çünkü iki anahtarın gerçekten bulunması gerekmez. Bu karma için doğru değildir, çünkü karma sonucu genellikle orijinal girişle aynı uzunlukta değildir.


1
Her şey doğru, ama sadece güçlü çarpışma direnci uzlaşmasının MD5 üzerindeki etkisinin biraz orantılı olduğunu belirtmek istiyorum - kripto karma işlevlerini kullanan çoğu senaryo güçlü çarpışma direncine, sadece zayıf dirence dayanmıyor. Bu güvenlik açığından etkilenmezler.
SquareCog

1

Çifte karma bana sadece şifreyi istemciye hash ve daha sonra bu karma hash (farklı tuz ile) sunucuya kaydedin.

Bu şekilde, birisi sunucuya girse bile (böylece SSL'nin sağladığı güvenlik göz ardı edilirse), net parolalara hala erişemez.

Evet, sisteme girmesi için gerekli verilere sahip olacak, ancak bu verileri kullanıcının sahip olduğu hesapların dışından ödün vermek için kullanamaz. Ve insanların hemen hemen her şey için aynı şifreyi kullandıkları bilinmektedir.

Açık şifreleri elde etmenin tek yolu istemciye bir keygen yüklemek - ve bu artık sizin probleminiz değil.

Kısacası:

  1. İstemcideki ilk karma, kullanıcılarınızı bir 'sunucu ihlali' senaryosunda korur.
  2. Sunucudaki ikinci karma, birisi veritabanı yedeklemenize sahipse sisteminizi korumaya yarar, bu nedenle hizmetlerinize bağlanmak için bu şifreleri kullanamaz.

1
+1 Bunun gibi bir cevap görmeyi bekliyordum, çünkü istemcide düz metin parolasını saklamak istemediğiniz aynı senaryoyu düşündüm, ancak aynı zamanda son şifrelenmiş parolayı tel üzerinden göndermeyin. DB ile basit karşılaştırma.
Mark

1
Web uygulamaları için yardımcı olmaz. sunucunuzun güvenliği ihlal edilirse, sunucunuzun istemciye gönderdiği kod da tehlikeye atılır. Saldırgan, istemci tarafındaki karmayı devre dışı bırakır ve ham parolaları yakalar.
Clement Cherlin

0

Arama alanını azaltma endişesi matematiksel olarak doğrudur, ancak arama alanı tüm pratik amaçlar için (tuz kullandığınız varsayılarak) 2 ^ 128'de yeterince büyük kalmaktadır. Ancak, parolalardan bahsettiğimiz için, zarf arkası hesaplamalarıma göre, olası 16 karakterli dizelerin (alfasayısal, büyük harf, atılan birkaç sembol) sayısı yaklaşık 2 ^ 98'dir. Dolayısıyla, arama alanındaki algılanan azalma gerçekten alakalı değildir.

Bunun dışında, kriptografik olarak gerçekten de hiçbir fark yok.

"Karma zinciri" adı verilen bir şifreleme ilkesi olmasına rağmen - kullanıldıktan sonra bir imza anahtarını açıklamak gibi, sistemin bütünlüğünden ödün vermeden bazı serin hileler yapmanızı sağlayan bir teknik - minimum zaman senkronizasyonu verildiğinde, bu ilk anahtar dağıtımı sorununu temiz bir şekilde ortadan kaldırmanızı sağlar. Temel olarak, büyük bir karma karması kümesini önceden hesaplarsınız - h (h (h (h .... (h (k)) ...))), işaretli bir aralıktan sonra imzalamak için n değerini kullanın. çıkarın ve (n-1) tuşunu kullanarak imzalayın. Alıcılar artık önceki tüm mesajları gönderdiğinizi doğrulayabilir ve geçerli olduğu süre geçtiği için hiç kimse imzanızı taklit edemez.

Bill'in önerdiği gibi yüz binlerce kez yeniden hash işlemek sadece cpu'nuzun israfıdır .. 128 bit kırma konusunda endişeleriniz varsa daha uzun bir anahtar kullanın.


1
Yeniden hashlama, hashı yavaşlatmakla ilgilidir. Bu, şifre tabanlı şifrelemede önemli bir güvenlik özelliğidir. PCKS5 ve PBKDF2 bağlantılarına bakın.
orip

0

Bu makaledeki bazı yanıtların önerdiği gibi, güvenliği artırabileceği bazı durumlar ve kesinlikle onu incittiği durumlar vardır. Güvenliği kesinlikle artıracak daha iyi bir çözüm var. Karma sayısını iki katına çıkarmak yerine, tuzunuzun boyutunu iki katına çıkarmak veya karmada kullanılan bit sayısını iki katına çıkarmak veya her ikisini birden yapmak yerine! SHA-245 yerine, SHA-512'ye atlayın.


Bu soruya cevap vermiyor.
Kertenkele Bill

1
Çift karma, çabaya değmez, ancak karma boyutunuzu iki katına çıkarır. Bunun daha değerli bir nokta olduğunu düşünüyorum.
Stefan Rusek

-1

Çifte hash çirkin, çünkü bir saldırganın çoğu hash ile gelmek için bir masa oluşturması daha olasıdır. Daha iyisi, karmalarınızı tuzlamak ve karmaları birlikte karıştırmaktır. Ayrıca, hashleri ​​(temelde tuzlama) "imzalamak" için yeni şemalar vardır, ancak daha güvenli bir şekilde.


-1

Evet.

Kesinlikle yok gibi geleneksel bir hash fonksiyonu birden tekrarlamalar kullanın md5(md5(md5(password))). En iyi ihtimalle güvenlikte marjinal bir artış elde edeceksiniz (bunun gibi bir şema, GPU saldırısına karşı neredeyse hiç koruma sağlamaz; sadece boru hattı oluşturun.) En kötüsü, eklediğiniz her yineleme ile karma alanınızı (ve böylece güvenliği) azaltırsınız. . Güvenlik içinde, en kötüsünü varsaymak akıllıca olacaktır.

Do bir şifre olduğunu oldu gelmiştir kullanmak tasarlanmış hem kaba kuvvet ve zaman-uzay saldırılarına etkili şifre karma ve dayanıklı olduğu bir yetkili Cryptographer tarafından. Bunlar bcrypt, scrypt ve bazı durumlarda PBKDF2'yi içerir. Glibc SHA-256 tabanlı karma da kabul edilebilir.


-1

Bir uzuv çıkacağım ve bazı durumlarda daha güvenli olduğunu söyleyeceğim ... yine de beni küçümseme!

Matematiksel / kriptografik bir bakış açısından, daha az güvenlidir, çünkü başkalarının size yapabileceğimden daha net bir açıklama yapacağından eminim.

ancak , "şifre" metnini MD5'ten daha fazla içerme olasılığı yüksek olan MD5 karmalarının büyük veritabanları vardır. Yani çift karma yaparak bu veritabanlarının etkinliğini azaltırsınız.

Tabii ki, bir tuz kullanırsanız, bu avantaj (dezavantaj?) Ortadan kalkar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.