it-swarm-eu.dev

Doporučený počet kol pro bcrypt

Jaký je dnes (červenec 2012) doporučený počet kol brypt pro hašování hesla pro průměrný web (ukládání pouze jména, emailaddress a domovské adresy, ale bez kreditní karty nebo lékařských informací)?

Jinými slovy, jaká je současná schopnost komunity pro šifrování hesel bcrypt? Několik knihoven bcrypt používá jako výchozí nastavení 12 kol (2 ^ 12 iterací). Je to doporučený pracovní faktor? Nebylo by 6 kol dostatečně silné (což se stane limitem pro hašování bcryptů na straně klienta v Javascriptu, viz také Výzva: výzva k zadání hesla na straně klienta a ověření hesla na straně server )?

Přečetl jsem odpověď https://security.stackexchange.com/a/3993/11197 , která dává hloubkovou diskusi o vyvážení různých faktorů (i když pro PBKDF2-SHA256). Hledám však skutečné číslo. Pravidlo.

94
Jason Smith

Myslím, že odpověď na všechny vaše otázky je již obsažena v odpověď Thomase Pornina . Spojili jste se s tím, takže o tom pravděpodobně víte, ale navrhuji, abyste si ji znovu přečetli.

Základní principy jsou: nevybírejte několik kol; místo toho vyberte dobu ověření hesla, kterou zabere váš server, a na základě toho vypočítejte počet kol. Chcete, aby ověření trvalo tak dlouho, jak vydržíte.

Pro některé příklady konkrétních čísel viz odpověď Thomase Pornina. Navrhuje, aby přiměřeným cílem bylo, aby ověření/hashování hesla trvalo 241 milisekund na heslo. (Poznámka: Thomas původně napsal "8 milisekund", což je špatně - toto je údaj o trpělivosti jednoho dne místo jednoho měsíce.) To stále umožňuje serveru ověřit 4 hesla za sekundu (více, pokud to dokážete paralelně). Thomas odhaduje, že pokud je to váš cíl, asi 20 000 kol je na správném parkovišti.

Optimální počet kol se však u vašeho procesoru změní. V ideálním případě byste srovnali, jak dlouho trvá váš procesor, a podle toho zvolte číslo. To netrvá tak dlouho; takže pro dosažení nejlepších výsledků stačí bičovat skript a zjistit, kolik kol je potřeba, aby bylo zajištěno, že hashování hesla trvá na vašem serveru asi 240 milisekund (nebo déle, pokud jej můžete nést).

41
D.W.

Když byla BCrypt poprvé zveřejněna, v roce 1999 uvedli výchozí nákladové faktory jejich implementace:

  • normální uživatel: 6
  • super uživatel: 8

Také si všimnou:

Ať už si lidé vyberou jakoukoli cenu, mělo by se čas od času přehodnotit

Šifrovací cena 6 znamená 64 kol (2 6  = 64).

Pokud použijeme tuto počáteční „normální uživatelskou“ hodnotu, chceme zkusit upravit výpočet inflace výkonu ( za předpokladu, že se průměrně zdvojnásobí každých 18 měsíců ).

R = R × 2(měsíce/18)
R = 64 × 2(měsíce/18)

Dnes (9. března 2015) je 171 měsíců od 31.12.1999 (nebo použijte 1/1/2000 pro jednoduchost), počet kol by se měl zdvojnásobit více než 9krát:

R = 64 × 2(171/18)
R = 64 × 29.5
R = 64 × 724,1
R = 46,341,0

Nakonec to chceme převést zpět na nákladový faktor

cena = ln (R)/ln (2)
náklady = ln (46 341,0)/ln (2)
náklady = 15,5

Praktičnost nákladového faktoru 15 závisí na výpočetním výkonu vašeho serveru. Například můj stolní počítač je procesor Intel Core i7-2700K s procesorem @ 3,50 GHz. Původně jsem srovnával implementaci BCrypt dne 23. 1. 2014:

1/23/2014  Intel Core i7-2700K CPU @ 3.50 GHz

| Cost | Iterations        |    Duration |
|------|-------------------|-------------|
|  8   |    256 iterations |     38.2 ms | <-- minimum allowed by BCrypt
|  9   |    512 iterations |     74.8 ms |
| 10   |  1,024 iterations |    152.4 ms | <-- current default (BCRYPT_COST=10)
| 11   |  2,048 iterations |    296.6 ms |
| 12   |  4,096 iterations |    594.3 ms |
| 13   |  8,192 iterations |  1,169.5 ms |
| 14   | 16,384 iterations |  2,338.8 ms |
| 15   | 32,768 iterations |  4,656.0 ms |
| 16   | 65,536 iterations |  9,302.2 ms |

Ale to byl rok 2014

Tato načasování byla původně vypočtena na začátku roku 2014. V mém výpočtu se mělo použít pouze 156 měsíců (spíše než 171) měsíců:

R = 64 × 2(156/18)
R = 64 × 28,66
R = 64 × 406,8
R = 26,035,2

cena = ln (R)/ln (2)
náklady = ln (26 035,2)/ln (2)
náklady = 14,7

Ale i7-2700K již byla ukončena

Model i7-2700K byl již ukončen (Q1 2013) v době, kdy jsem spustil své referenční hodnoty. Byla vydána a byla nejmodernější ve 4. čtvrtletí 2011. Pokud spustím čísla za 4. čtvrtletí 2011:

R = 64 × 2(129/18)
R = 64 × 27.16
R = 64 × 143,7
R = 9,196,8

cena = ln (R)/ln (2)
náklady = ln (9,196,8)/ln (2)
náklady = 13,2

Cena 13 je na mé ploše, téměř 2 sekundy přes sekundu.

Jak dlouho to vydržíte?

To vám dává chuť na zpoždění, které původní implementátoři zvažovali, když to napsali: ~ 0,5-1 sekundy.

Ale samozřejmě, čím déle vydržíte, tím lépe. Každá implementace BCrypt, kterou jsem viděl, používal 10 jako výchozí cena. A moje implementace to použilo. Věřím, že je čas, abych zvýšil výchozí náklady na 12.

Budoucí korektury

Mohu také změnit hashovací funkci:

hash = HashPassword("correct battery horse stapler");

tj. ta, kde se spoléháte na výchozí cenu, namísto toho použijte automaticky posuvnou cenu. Tímto způsobem se cena časem zvyšuje. Měnící se:

String HashPassword(String password)
{
   return BCrypt.HashPassword(password, BCRYPT_DEFAULT_COST);
}

na něco jako:

String HashPassword(String password)
{  
   /*
     Rather than using a fixed default cost, run a micro-benchmark
     to figure out how fast the CPU is.
     Use that to make sure that it takes **at least** 250ms to calculate
     the hash
   */
   Int32 costFactor = this.CalculateIdealCost();
   //Never use a cost lower than the default hard-coded cost
   if (costFactor < BCRYPT_DEFAULT_COST) 
      costFactor = BCRYPT_DEFAULT_COST;

   return BCrypt.HashPassword(password, costFactor);
}

Int32 CalculateIdealCost()
{
    //Benchmark using a cost of 5 (the second-lowest allowed)
    Int32 cost = 5;

    var sw = new Stopwatch();
    sw.Start();
    this.HashPassword("microbenchmark", cost);
    sw.Stop();

    Double durationMS = sw.Elapsed.TotalMilliseconds;

    //Increasing cost by 1 would double the run time.
    //Keep increasing cost until the estimated duration is over 250 ms
    while (durationMS < 250)
    {
       cost += 1;
       durationMS *= 2;
    }

    return cost;
}

Upravit 3/12/2015 : Aktualizovaná čísla rychlosti. 32bitový kompilátor Delphi XE6 (c.2013) generuje kód o řádovou rychlost rychleji než Delphi 5 (c.1999) pro stejný procesor. 64bitový kompilátor Delphi XE6 generuje kód o 20% pomaleji než 32bitový kompilátor.

61
Ian Boyd

Silnější derivace klíčů pomocí sekvenčních funkcí s pevnou pamětí je velmi dobrý příspěvek na téma natahování klíčů. Na straně 14 porovnává různé hashovací algoritmy s tím, kolik peněz bude stát za rozbití hashe, což je užitečný způsob přemýšlení o těchto věcech. (Pokud není modul TPM k dispozici, používá ChromeOS poznámku Scrypt.)

Myšlenka je, že chcete, aby tyto hashe hesla byly nepřerušené co nejdéle. Podle Mooreova zákona je to exponenciálně rychle se pohybující cíl. Scrypt používá proměnné množství paměti a CPU, tato proměnná by se v závislosti na čase mohla stát těžší. V tom, že pokaždé, když se klient přihlásí, můžete aktualizovat hash hesla, aby byla bezpečnější. V případě PBKDF2 by to mohlo vypadat jako rounds=2^(current_year-2000) nebo něco takového.

Je důležité si uvědomit, že toto zpracování nemůžete pouze přenést na klienta a očekávat, že váš protokol bude zabezpečený. Všechny klientské ověřovací protokoly hašování, které znám, vyžadují, aby server provedl identický výpočet, aby ověřil ověřovací údaje (NTLM, NTLMv2, SRP, WPA-PSK ...).

3
rook