Zgoščevanje gesel

Da bi zagotovili varnost naših uporabnikov, ne shranjujemo njihovih gesel v berljivi obliki, ampak shranimo samo odtis (t.i. hash). Iz odtisa ni mogoče nazaj rekonstruirati prvotne oblike gesla. Pomembno je uporabiti varen algoritem, s katerim odtis ustvarimo. Pri tem nam pomaga razred Nette\Security\Passwords.

Namestitev in zahteve

Ogrodje samodejno dodaja v DI vsebnik storitev tipa Nette\Security\Passwords pod imenom security.passwords, do katere pridete tako, da si jo pustite predati s pomočjo dependency injection.

use Nette\Security\Passwords;

class Foo
{
	public function __construct(
		private Passwords $passwords,
	) {
	}
}

__construct ($algo=PASSWORD_DEFAULT, array $options=[])string

Izberemo, kateri varen algoritem za generiranje hasha uporabiti in konfiguriramo njegove parametre.

Kot privzeto se uporablja PASSWORD_DEFAULT, torej se izbira algoritma prepušča PHP-ju. Algoritem se lahko v novejših različicah PHP spremeni, če se pojavijo novejši, močnejši hash algoritmi. Zato se morate zavedati, da se lahko dolžina nastalega hasha spremeni, in ga shranite na način, ki lahko sprejme dovolj znakov, 255 je priporočena širina.

Primer nastavitve hitrosti zgoščevanja z algoritmom bcrypt s spremembo parametra cost: (leta 2020 je privzeto 10, zgoščevanje gesla traja približno 80ms, za cost 11 je to cca 160ms, za cost 12 približno 320ms, počasneje kot je, boljša je zaščita, pri čemer se hitrost 10–12 že šteje za zadostno zaščito)

// bomo gesla zgoščevali z 2^12 (2^cost) iteracijami algoritma bcrypt
$passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);

S pomočjo dependency injection:

services:
	security.passwords: Nette\Security\Passwords(::PASSWORD_BCRYPT, [cost: 12])

hash (string $passwords): string

Generira hash gesla.

$res = $passwords->hash($password); // Zgošči geslo

Rezultat $res je niz, ki poleg samega hasha vsebuje tudi identifikator uporabljenega algoritma, njegove nastavitve in kriptografsko sol (naključni podatki, ki zagotavljajo, da se za isto geslo generira drugačen hash). Je torej nazaj združljiv, ko na primer spremenite parametre, tako da se bodo tudi hashi, shranjeni z uporabo prejšnjih nastavitev, lahko preverili. Celoten ta rezultat se shranjuje v podatkovno bazo, zato ni treba shranjevati soli ali nastavitev posebej.

verify (string $password, string $hash)bool

Ugotovi, ali dano geslo ustreza danemu odtisu. $hash pridobite iz podatkovne baze glede na vneseno uporabniško ime ali e-poštni naslov.

if ($passwords->verify($password, $hash)) {
	// pravilno geslo
}

needsRehash (string $hash): bool

Ugotovi, ali hash ustreza v konstruktorju navedenim možnostim.

Uporabno je v trenutku, ko na primer spreminjate hitrost zgoščevanja. Preverjanje poteka glede na shranjene nastavitve in če needsRehash() vrne true, je treba ponovno ustvariti hash, tokrat z novimi parametri, in ga ponovno shraniti v podatkovno bazo. Tako se samodejno “nadgradijo” shranjeni hashi ob prijavi uporabnikov.

if ($passwords->needsRehash($hash)) {
	$hash = $passwords->hash($password);
	// shraniti $hash v podatkovno bazo
}
različica: 4.0