Nette Documentation Preview

syntax
Jelszó hashelés
***************
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Jelszó hashelés

Annak érdekében, hogy biztosítsuk felhasználóink biztonságát, nem tároljuk jelszavaikat olvasható formában, hanem csak a lenyomatukat (ún. hash) tároljuk. A lenyomatból nem lehet visszafejteni a jelszó eredeti formáját. Fontos, hogy biztonságos algoritmust használjunk a lenyomat létrehozásához. Ebben segít nekünk a Nette\Security\Passwords osztály.

Telepítés és követelmények

A keretrendszer automatikusan hozzáadja a DI konténerhez a Nette\Security\Passwords típusú szolgáltatást security.passwords néven, amelyhez úgy juthat hozzá, hogy dependency injection segítségével kéri át.

use Nette\Security\Passwords;

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

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

Kiválasztjuk, melyik biztonságos algoritmust használjuk a hash generálásához, és konfiguráljuk annak paramétereit.

Alapértelmezés szerint a PASSWORD_DEFAULT használatos, tehát az algoritmus kiválasztása a PHP-ra van bízva. Az algoritmus megváltozhat a PHP újabb verzióiban, ha újabb, erősebb hashelési algoritmusok jelennek meg. Ezért tudatában kell lennie annak, hogy az eredményül kapott hash hossza megváltozhat, és olyan módon kell tárolnia, amely elegendő karaktert képes befogadni, a 255 az ajánlott szélesség.

Példa a bcrypt algoritmus hashelési sebességének beállítására a cost paraméter megváltoztatásával: (2020-ban az alapértelmezett 10, a jelszó hashelése kb. 80ms-ig tart, a cost 11 esetén kb. 160ms, a cost 12 esetén kb. 320ms, minél lassabb, annál jobb a védelem, miközben a 10–12 sebesség már elegendő védelemnek számít)

// a jelszavakat a bcrypt algoritmus 2^12 (2^cost) iterációjával fogjuk hashelni
$passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);

Dependency injection segítségével:

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

hash(string $password): string

Generálja a jelszó hash-ét.

$res = $passwords->hash($password); // Hasheli a jelszót

Az $res eredmény egy string, amely a maga hash-én kívül tartalmazza a használt algoritmus azonosítóját, annak beállításait és a kriptográfiai salt-ot (véletlenszerű adatok, amelyek biztosítják, hogy ugyanahhoz a jelszóhoz más hash generálódjon). Tehát visszafelé kompatibilis, ha például megváltoztatja a paramétereket, akkor az előző beállításokkal tárolt hash-ek is ellenőrizhetők lesznek. Ez az egész eredmény az adatbázisba kerül mentésre, így nincs szükség a salt vagy a beállítások külön tárolására.

verify(string $password, string $hash)bool

Megállapítja, hogy az adott jelszó megfelel-e az adott lenyomatnak. Az $hash-t az adatbázisból szerezze be a megadott felhasználónév vagy e-mail cím alapján.

if ($passwords->verify($password, $hash)) {
	// helyes jelszó
}

needsRehash(string $hash): bool

Megállapítja, hogy a hash megfelel-e a konstruktorban megadott opcióknak.

Hasznos lehet abban a pillanatban, amikor pl. megváltoztatja a hashelési sebességet. Az ellenőrzés a tárolt beállítások szerint történik, és ha a needsRehash() true-t ad vissza, akkor újra létre kell hozni a hash-t, ezúttal az új paraméterekkel, és újra el kell menteni az adatbázisba. Így automatikusan „frissülnek“ a tárolt hash-ek a felhasználók bejelentkezésekor.

if ($passwords->needsRehash($hash)) {
	$hash = $passwords->hash($password);
	// $hash mentése az adatbázisba
}