Хеширане на пароли
За да гарантираме сигурността на нашите потребители, ние никога не съхраняваме паролите им в чист текст, а вместо това съхраняваме хеш на паролата. Hashing не е обратима операция, паролата не може да бъде възстановена. Въпреки това паролата може да бъде разбита и за да направим разбиването възможно най-трудно, трябва да използваме сигурен алгоритъм. Класът Nette\Security\Passwords ще ни помогне в това.
Фреймуъркът автоматично добавя услугата Nette\Security\Passwords
към
контейнера DI под името security.passwords
, което получавате, като го
предавате чрез инжектиране
на зависимости:
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 и да промените скоростта на хеширане от стойността по подразбиране от 10 с параметъра cost. През 2020 г. при цена 10 хеширането на една парола отнема приблизително 80 ms, при цена 11 – 160 ms, а при цена 12 – 320 ms, като скалата е логаритмична. Колкото по-бавно, толкова по-добре, а цената 10–12 се счита за достатъчно бавна за повечето приложения:
// ще хешираме паролите с 2^12 (2^cost) итерации на алгоритъма bcrypt
$passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);
С инжектиране на зависимости:
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 в базата данни
}