Hashování hesel pomocí PHP 5.5 Password Hashing API

Zdroj: SOOM.cz [ISSN 1804-7270]
Autor: ScheRas
Datum: 18.9.2013
Hodnocení/Hlasovalo: 1/18

V současné době je používání bcryptu nejpřijatelnější způsob pro hashování hesel, ale velké množství vývojářů stále používá starší a slabší algoritmy jako MD5 nebo SHA1.

Tento článek je překladem originálu "Hashing Passwords with the PHP 5.5 Password Hashing API" od Sandeepa Pandy, který vyšel na webu www.sitepoint.com.

V současné době je používání bcryptu nejpřijatelnější způsob pro hashování hesel, ale velké množství vývojářů stále používá starší a slabší algoritmy jako MD5 nebo SHA1. Někteří vývojáři dokonce stále při hashování nepoužívají salt. Nové Hashing API v PHP 5.5 si klade za cíl upozornit na bcrypt a přitom příliš neukazovat jeho složitosti. V tomto článku se pokusím pokrýt základy používání nového hashovací API v PHP.

Nové Password Hashing API představuje čtyři jednoduché funkce:


password_hash()

Přestože je funkce crypt() bezpečná, je považována za příliš složitou a příliš náchylnou na programátorské chyby. Proto někteří vývojáři raději použijí pro generování hashe slabší sůl a algoritmus, například:

Funkce password_hash() může ovšem ulehčit náš život a náš kód může být bezpečný. Pokud potřebujete vytvořit hash hesla, stačí ho svěřit funkci, která vrátí řetězec, jenž můžete s klidem uložit do databáze.

To je ono! Prvním parametrem je heslo, z kterého potřebujeme vytvořit hash a druhý parametr specifikuje algoritmus, který má být použit pro generování hashe.

Výchozím algoritmem je v současnosti bcrypt, ale to se může v budoucnu klidně změnit a jako výchozí algoritmy mohou být použity silnější a bezpečnější šifry generující silnější hashe. Pokud se chystáte použít PASSWORD_DEFAULT ve vašem projektu, ujistěte se, že velikost databázového sloupce je větší, než 60 znaků. Nastavení velikosti na 255 znaků se jeví jako optimální volba. Můžete také použít PASSWORD_BCRYPT jako druhý parametr. V tomto případě bude výsledek vždy dlouhý 60 znaků.

Důležitou věcí, které jste si jistě všimli, je, že jsme funkci nepředali žádný salt ani cost. Nové API se o to postará za nás. Navíc je sůl součástí hashe, takže ho nemusíte ukládat zvlášť. Pokud chcete přeci jen předat vlastní salt (nebo cost), můžete tak učinit nastavením třetího argumentu, totiž pole možností.

 custom_function_for_salt(), //Vlastní kód pro generování vhodného saltu
    'cost' => 12 //výchozí hodnota je 10
		];
 $hash = password_hash($password, PASSWORD_DEFAULT, $options);
?>

V tomto případě budete vždy držet krok s novými bezpečnostními opatřeními. Pokud se vývojáři PHP rozhodnou později implementovat silnější hashovací algoritmus, váše aplikace to ihned využije.


password_verify()

Už jsme si ukázali, jak generovat hashe pomocí nového API, tak se teď pojďme kouknout na to, jak hesla ověřovat. Uvědomme si, že do databáze ukládáme hashe, ale od uživatele dostaneme heslo jako prostý text.

Funkce password_verify() vezme heslo a hash jako své argumenty. Pokud se heslo rovná danému hashi, funkce vrátí TRUE.


Připomeňme si, že sůl je součástí hashe, takže není potřeba jí nijak zvlášť specifikovat.


password_needs_rehash()

Co když potřebujete změnit salt nebo cost parametr hashe? Co když se rozhodnete zvýšit bezpečnost aplikace přidáním soli nebo zvětšením cost parametru? Krom toho může PHP změnit výchozí algoritmus. Ve všech těchto případech budete asi chtít přehashovat stávající hesla. Funkce password_needs_rehash() pomáhá otestovat, zda-li byl hash vytvořený pomocí konkrétního algoritmu a byly použity konkrétní možnosti saltu a costu.

 12])) {
    // Heslo by mě mělo být přehashováno, jelikož nebylo vytvořeno pomocí aktuálního algoritmu
    $hash = password_hash($password, PASSWORD_DEFAULT, ['cost' => 12]);
    // Nezapomeňte uložit nový hash.
  }
?>

password_get_info()

Funkce password_get_info() přijímá jako jediný argument hash vytvořený funkcí password_hash() a vrací asociativní pole o třech prvcích:


Závěr

Práce s novým Password Hashing API je rozhodně jednodušší než neobratná manipulace s funkcí crypt(). Pokud vaše webová aplikace běží na PHP 5.5, pak důrazně doporučuji používat nové hashovací API. Ti kteří používají PHP 5.3.7 (nebo pozdější) mohou použít knihovnu nazvanou password_compat, která emuluje API a sama se zakáže při přechodu na PHP 5.5.