Hashování hesel

Abychom zajistili bezpečnost našich uživatelů, neukládáme jejich hesla v čitelné podobě, ale uložíme si pouze otisk (tzv. hash). Z otisku nelze zpětně zrekonstruovat původní podobu hesla. Je důležité použít bezpečný algoritmus, kterým otisk vytvoříme. S tím nám pomůže statická třída Nette\Security\Passwords.

Instalace:

composer require nette/utils

Všechny příklady předpokládají vytvořený alias:

use Nette\Security\Passwords;

hash(string $passwords, array $options=null)string

Vygeneruje hash hesla pomocí moderního algoritmu bcrypt. Můžeme určit parametr cost z rozsahu 4–31, který udává kolik iterací algoritmu má proběhnout a měníte tím rychlost hashování. Pokud parametr neurčíme, bude použita výchozí hodnota 10.

V roce 2020 s hodnotou cost 10 trvá hashování hesla velmi zhruba 80ms, pro cost 11 je to cca 160ms, pro cost 12 zhruba 320ms, čím pomalejší, tím lepší ochrana, přičemž rychlost 10–12 se již považuje za ochranu dostatečnou.

$hash = Passwords::hash($password); // Zahashuje heslo
$hash = Passwords::hash($password, ['cost' => 12]); // Zahashuje heslo 2^12 iteracemi algoritmu bcrypt

Výsledek $hash obsahuje identifikátor použitého algoritmu i jeho nastavení, kryptografickou sůl i samotný hash. Je tedy zpětně kompatibilní, když například změníte parametry, tak i hashe uložené s použitím předchozího nastavení půjdou ověřit. Celý tento výsledek se ukládá do databáze, takže není potřeba ukládat sůl nebo nastavení zvlášť.

verify(string $password, string $hash)bool

Zjistí, zda dané heslo odpovídá danému otisku. $hash získejte z databáze podle zadaného uživatelského jména nebo e-mailové adresy.

if (Passwords::verify($password, $hash)) {
	// správné heslo
}

needsRehash(string $password, array $options=null)bool

Zjistí, zda hash odpovídá zadaným volbám. Můžeme nastavit cost v rozsahu 4–31, který udává kolik iterací algoritmu má proběhnout. Pokud parametr neurčíme, bude použita výchozí hodnota 10.

Hodí se použít ve chvíli, kdy např. měníte rychlost hashování. Ověření proběhne podle uloženého nastavení a pokud needsRehash() vrátí true, tak je potřeba znovu vytvořit hash, tentokrát s novými parametry, a uložit ho znovu do databáze. Takto se automaticky „upgradují“ uložené hashe při přihlašování uživatelů.

if (Passwords::needsRehash($hash, $options)) {
	$hash = Passwords::hash($password, $options);
	// uložit $hash do databáze
}
verze: 4.0 3.x 2.x