it-swarm-eu.dev

Hashing hesla: přidejte sůl + pepř nebo je dost soli?

Poznámka: Jsem si vědom, že správnou metodou pro zabezpečení hashováním heslem je buď šifrování, nebo šifrování. Tato otázka není pro implementaci do skutečného softwaru, je to pro mé vlastní pochopení.

Související


Pozadí
Pokud vím, doporučeným/schváleným způsobem ukládání ověřovatelů hesel je ukládání:

$verifier = $salt + hash( $salt + $password )

Kde:

  • hash() je kryptografický hashovací algoritmus
  • $salt Je náhodná, rovnoměrně distribuovaná vysoká entropická hodnota
  • $password Je heslo zadané uživatelem

Někteří lidé doporučují přidat tajný klíč do mixu (někdy nazývaný pepř ). Kde je pepř tajná, vysoká entropie, systémově specifická konstanta.

Zdá se, že důvodem je, že i když se útočník zmocní ověřovatelů hesla, existuje velká šance, že nezná hodnotu pepře. Montáž úspěšného útoku se tak stává těžší.

Takže moje otázka zní:
Zvyšuje přidávání hodnoty pepře kromě soli, když hashovací hesla zvyšují celkovou bezpečnost?

Nebo je vnímaná zvýšená bezpečnost založena na falešných předpokladech?

Rychlá aktualizace
Znám účel $salt (Napsal jsem docela dlouhou odpověď o StackOverflow o tom) další $pepper Klíč je ne zlepšování toho, co sůl dělá.
Otázka zní, přidává $pepper Zabezpečení jiné, než co sůl dělá?

234
Jacco

V některých případech mohou být papriky užitečné.

Jako typický příklad řekněme vytváříte webovou aplikaci. Skládá se z kódu webapp (spuštěného v nějakém rámci webapp, ASP.NET MVC, Pyramida na Pythonu, na tom nezáleží) a databáze SQL pro uložení. Webapp a SQL DB běží na různých fyzických serverech.

Nejběžnějším útokem proti databázi je úspěšný SQL Injection Attack. Tento druh útoku nemusí nutně získat přístup k vašemu kódu webapp, protože webapp běží na jiném serveru a ID uživatele.

Musíte hesla bezpečně ukládat do databáze a přijít s něčím, co ve formě:

$hashed_password = hash( $salt . $password )

kde $salt je uložen v prostém textu v databázi, spolu s reprezentací $hashed_password a náhodně vybrané pro každé nové nebo změněné heslo.

nejdůležitějším aspektem každého schématu hašování hesel je, že hash je pomalý kryptograficky bezpečná hashovací funkce, viz https://security.stackexchange.com/a/31846/10727 , kde najdete další informace o pozadí.

Otázkou tedy je vzhledem k tomu, že je téměř nulové úsilí přidat do kódu aplikace konstantní hodnotu a že kód aplikace bude obvykle not být kompromitován během SQL Injection Attack, je tedy následující podstatně lepší než výše uvedené?

$hashed_password = hash( $pepper . $salt . $password )

kde $salt je uložen v holém textu v databázi a $pepper je konstanta uložená v holém textu v aplikačním kódu (nebo konfiguraci, pokud je kód použit na více serverech nebo je-li zdroj veřejný).

Přidání této položky $pepper Je snadné - ve svém kódu pouze vytváříte konstantu, zadáváte do ní velkou kryptograficky bezpečnou náhodnou hodnotu (například 32 bajtů z/dev/urandom hex nebo base64 kódované) a pomocí tohoto konstanta ve funkci hashování hesla. Pokud již máte stávající uživatele, potřebujete migrační strategii, například na další přihlašovací heslo znovu naformátujte a vedle hash uložte číslo verze strategie hashování heslem.

Odpovědět:

Pomocí $pepper se přidá k síle hash hesla , pokud kompromis databáze neimplikuje kompromis aplikace. Bez znalosti pepře zůstanou hesla zcela bezpečná. Díky soli specifické pro heslo si ani nemůžete zjistit, zda jsou dvě hesla v databázi stejná nebo ne.

Důvod je ten, že hash($pepper . $salt . $password) efektivně vytváří pseudonáhodnou funkci s $pepper Jako klíč a $salt.$password Jako vstup (pro rozumné hash kandidáty jako PBKDF2 s SHA * , bcrypt nebo scrypt). Dvě ze záruk pseudonáhodné funkce jsou, že nemůžete odvodit vstup z výstupu pod tajným klíčem a ani výstup ze vstupu bez znalosti klíče. To zní hodně jako jednosměrná vlastnost hash funkcí, ale rozdíl spočívá ve skutečnosti, že s nízkými hodnotami entropie, jako jsou hesla, můžete efektivně vyjmenovat všechny možné hodnoty a vypočítat obrázky pod veřejnou hashovací funkcí, a tak najít hodnotu, jejíž obrázek odpovídá předběžnému obrazu. S pseudonáhodnou funkcí to nemůžete udělat bez klíče (tj. Bez pepře), protože bez klíče ani nemůžete vypočítat obraz jedné hodnoty.

Důležitá role $salt V tomto nastavení přichází do hry, pokud máte přístup k databázi po delší dobu a stále můžete s aplikací pracovat zvenčí. Bez $salt Byste mohli nastavit heslo účtu, který ovládáte, na známou hodnotu $passwordKnown A porovnat hash s heslem neznámého hesla $passwordSecret. Jako hash($pepper . $passwordKnown)==hash($pepper . $passwordSecret) if a only if $passwordKnown==$passwordSecret Můžete porovnat neznámé heslo s jakoukoli vybranou hodnotou (jako technický předpoklad předpokládám kolizní odolnost hashovací funkce). Ale se solí dostanete hash($pepper . $salt1 . $passwordKnown)==hash($pepper . $salt2 . $passwordSecret) tehdy a jen tehdy, pokud $salt1 . $passwordKnown == $salt2 . $passwordSecret A jako $salt1 A $salt2 Byly náhodně vybrány pro $passwordKnown Resp. $passwordSecret Soli nikdy nebudou stejné (za předpokladu dostatečně velkých náhodných hodnot, jako je 256 bitů), takže již nebudete moci vzájemně porovnávat heslo.

195
Jesper M

(Poznámka: použití soli je jen polovina úlohy; musíte také zpomalit hašovací funkci - takže útok na jedno heslo s nízkou entropií je stále obtížný. Pomalu se obvykle dosahuje pomocí více iterací nebo hašováním zřetězení 10 000 kopií soli a hesla.)

Co váš „pepř“ dělá, je to, že transformuje hash na MAC . Vytváření dobrého a bezpečného MAC z hašovací funkce není snadné, takže byste raději měli použít HMAC místo domácí konstrukce (teoretický způsob uvedení je to, že hashovací funkce odolná proti kolizi není nutně nerozeznatelná od náhodného Oracle).

S MAC můžete získat jistotu v následujícím smyslu: přístup ke čtení databáze útočníkem by mohl přestat být skutečným problémem. Klávesa MAC ("pepř") může soustředit potřebu důvěrnosti. To se však spoléhá na to, že MAC je také jednosměrná funkce, což je vlastnost, kterou získáte z mnoha konstrukcí MAC (včetně HMAC), ale která není kryptograficky řečeno zaručena (existují jemnosti).

„Pepř“ znamená, že máte klíč ke správě, včetně zabezpečeného úložiště způsobem, který odolává restartu počítače. Klíč je malý a hodí se do paměti RAM, ale kvůli požadavkům na úložiště není jasné, zda skutečně zvyšuje zabezpečení. Útočník, který umí číst celou databázi, obvykle dokáže přečíst také celý pevný disk, včetně jakéhokoli "chráněného" souboru. Malá velikost klíče může umožnit některá pokročilá nastavení, např. klíč je uložen na čipových kartách, které se používají v době bootování, ale poté nejsou připojeny. Stručně řečeno, to, zda pepř stojí za námahu, záleží na kontextu - obecně bych to doporučil proti, aby se zabránilo další složitosti.

90
Thomas Pornin

Chtěl bych poukázat na to, co pepř opravdu dokáže.

Kdy pomůže pepř?

Jak již zdůraznili ostatní, přidání pepře je pouze výhodou, pokud má útočník přístup k hodnotám hash v databázi, ale nemá žádnou kontrolu nad serverem, a proto nemá pepř nezná). To je typické pro SQL-injection, pravděpodobně jeden z častěji používaných útoků, protože je to tak snadné.

Co zlepšuje pepř?

$hashValue = bcrypt('12345', $cost, $salt);

Toto heslo můžete snadno získat pomocí slovníkového útoku, i když jste správně použili funkci odvození klíčů. Vložte nejpoužívanější hesla do slovníku a hrubou silou použijte tato slabá hesla. Je velmi pravděpodobné, že najdeme heslo (příliš) v mnoha případech.

$hashValue = bcrypt('12345anm8e3M-83*2cQ1mlZaU', $cost, $salt);

S pepřem se slabé heslo zvětšuje na délku, obsahuje nyní speciální znaky, a co je důležitější, najdete ho v žádném slovníku. Takže, pokud pepř zůstane v tajnosti, tak zabrání útokům ve slovník, v tomto případě může chránit slabá hesla.

Upravit:

Existuje lepší způsob, jak přidat serverový klíč, než použít jako pepř. S pepřem musí útočník získat další oprávnění na serveru, aby získal klíč. Stejnou výhodu získáme výpočtem hash první, a poté šifrování hash pomocí postranního klíče serveru (obousměrné šifrování). To nám dává možnost vyměnit klíč, kdykoli je to nutné.

$hash = bcrypt($passwort, $salt);
$encryptedHash = encrypt($hash, $serverSideKey);
26
martinstoeckli

Příspěvek o vynálezu solení a iterací pro unixová hesla ( Zabezpečení hesel: Case Case, Morris & Thompson, 1978 ), také popisuje ekvivalent pepře:

Prvních osm znaků hesla uživatele se používá jako klíč pro DES; pak se algoritmus používá k šifrování konstanty. I když je tato konstanta v tuto chvíli nulová, je snadno přístupná a může být závislá na instalaci.

Neslyšel jsem však, že by se to používalo. Má ještě někdo?

9
nealmcb

Pouze BTW, nové NIST Digital Idendity Guidelines (Draft) důrazně doporučujeme použít také Pepř:

https://pages.nist.gov/800-63-3/sp800-63b.html#sec5

5.1.1.2 Ověřovatel zapamatovaných tajemství:

... hashovaná funkce s klíčem (např. HMAC [FIPS198-1]), přičemž klíč je uložen odděleně od hashovaných autentizátorů (např. V hardwarovém bezpečnostním modulu), Měl by být použit k dalšímu odporu proti slovníkovým útokům proti uloženým hašovacím autentizátorům.

7
eckes

Zvažte tento scénář:

Chystám se proniknout na web X pomocí injekce SQL, abych získal seznam uživatelů, s jejich hashe heslem a solí. Předpokládejme, že web X používá také globální pepř.

Jediné, co bych musel udělat, by bylo zaregistrovat uživatele na webu X s uživatelským jménem a heslem známým před injekcí SQL. Pak bych věděl, pro konkrétní záznam v databázi, heslo hash, prostý text heslo, sůl (uložená jako prostý text) a bylo by pro mne počítačově triviální prolomit globální pepř na základě tohoto jediného záznamu .

Takže opravdu, pepř by byl způsob, jak zpomalit útočníka na triviální množství režijního času. Nemuseli by hrubě vynucovat heslo + sůl + pepř, jak bylo zamýšleno, pouze pepř.

Výše uvedené je forma vybraný útok prostého text. Pokud útočníci znají algoritmus (hash ()), výstup ($ hashed_password) a všechny kromě jednoho ze vstupů („konstanty“ $ sůl a $ heslo a „proměnná“ $ pepř), mohou „vyřešit x“ "jako lineární algebraická rovnice (h = s + p + x == hsp = x), ale samozřejmě hrubou silou. Prodloužení pepře déle než 56 bajtů (448 bitů), bcryptův limit, zvyšuje časové náklady a je stejně dobré jako bcrypt, ale stále nemusí být tak dobré jako scrypt. Pokud je paprika dostatečně dlouhá, jedná se o vylepšení.

4
Alex R

Není příliš obeznámen s tím, jak by server mohl skrýt globální pepřovou konstantu, ale podle mého názoru hacker, který pronikl na server, přijde na to, jak zachytit hodnotu pepře. Aby byla hodnota pepře zcela bezpečná, vyžadovalo by to speciální hardware. Jedním ze způsobů, jak toho dosáhnout, by bylo použití desky FPGA nainstalované na serveru. FPGA by obsahoval kód používaný k provedení hash včetně hodnoty pepře a všechny výpočty hash probíhají uvnitř FPGA. S FPGA může být programování jednosměrná funkce. Pepř lze naprogramovat, ale neexistuje žádná instrukce, kterou by bylo možné poslat zpět. Pepř by byl uložen na kusu papíru uzamčeného v trezoru. Pokud je pepř 128+ bitů generovaných náhodně, neexistuje žádný praktický způsob, jak jej určit.
Nejste si jisti, jak by to bylo praktické, protože by to zvýšilo náklady na hardware na serveru.

1
Brian Sparks