Хеширане на пароли

За да осигурим сигурността на нашите потребители, не съхраняваме техните пароли в четим вид, а си запазваме само отпечатък (т.нар. хеш). От отпечатъка не може обратно да се реконструира оригиналният вид на паролата. Важно е да се използва сигурен алгоритъм, с който да създадем отпечатъка. С това ни помага класът Nette\Security\Passwords.

Инсталация и изисквания

Framework-ът автоматично добавя към DI контейнера услуга от тип Nette\Security\Passwords под името security.passwords, до която можете да стигнете, като си я поискате чрез dependency injection.

use Nette\Security\Passwords;

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

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

Избираме кой сигурен алгоритъм за генериране на хеш да използваме и конфигурираме неговите параметри.

По подразбиране се използва PASSWORD_DEFAULT, тоест изборът на алгоритъм се оставя на PHP. Алгоритъмът може да се промени в по-нови версии на PHP, ако се появят по-нови, по-силни хеширащи алгоритми. Затова трябва да сте наясно, че дължината на получения хеш може да се промени и трябва да го съхранявате по начин, който може да побере достатъчно знаци, 255 е препоръчителната ширина.

Пример за настройка на скоростта на хеширане с алгоритъм bcrypt чрез промяна на параметъра cost: (през 2020 г. по подразбиране е 10, хеширането на парола отнема около 80ms, за cost 11 е около 160ms, за cost 12 около 320ms, колкото по-бавно, толкова по-добра защита, като скорост 10–12 вече се счита за достатъчна защита)

// ще хешираме паролите с 2^12 (2^cost) итерации на алгоритъма bcrypt
$passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);

С помощта на dependency injection:

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

hash (string $passwords): string

Генерира хеш на паролата.

$res = $passwords->hash($password); // Хешира паролата

Резултатът $res е низ, който освен самия хеш съдържа и идентификатор на използвания алгоритъм, неговите настройки и криптографска сол (случайни данни, осигуряващи, че за една и съща парола се генерира различен хеш). Той е обратно съвместим, когато например промените параметрите, така че и хешовете, съхранени с използване на предишните настройки, ще могат да бъдат проверени. Целият този резултат се съхранява в базата данни, така че не е необходимо да се съхраняват солта или настройките отделно.

verify (string $password, string $hash)bool

Установява дали дадена парола съответства на дадения отпечатък. $hash вземете от базата данни според зададеното потребителско име или имейл адрес.

if ($passwords->verify($password, $hash)) {
	// правилна парола
}

needsRehash (string $hash): bool

Установява дали хешът съответства на зададените в конструктора опции.

Полезно е да се използва в момент, когато напр. променяте скоростта на хеширане. Проверката се извършва според съхранените настройки и ако needsRehash() върне true, тогава е необходимо отново да се създаде хеш, този път с новите параметри, и да се съхрани отново в базата данни. Така автоматично се “надграждат” съхранените хешове при влизане на потребителите.

if ($passwords->needsRehash($hash)) {
	$hash = $passwords->hash($password);
	// съхрани $hash в базата данни
}
версия: 4.0