Blowfish hash v PHP

Ve verzi PHP < 5.3.7 sice lze Blowfish hash získat pomocí volání metody crypt(), nicméně občas to prostě zlobí – viz CRYPT_BLOWFISH security fix details.

Pro verzi PHP >= 5.3.7 a PHP < 5.5 již má funkce crypt() bug opraven a doporučuji použít wrapper nad crypt() ircmaxell / password_compat implementující password_* funkce tak jak je známe z PHP 5.5.

Pro PHP >= 5.5 stačí použít nativní password_* funkce.

A nakonec 2 malé postřehy:

Pokud dobře nastavíte, tak se salt pro Blowfish hash generuje automaticky. Toto zvyšuje při dobrém nastavení generující fukce bezpečnost – nemusí se řešit unikátnost, nahodilost a délka saltu.  Nicméně salt je uložen v řetězci s hashem. takže nastává podobná situace jako u SHA nebo MD5 se saltem. Pokud se někdo dostane k hashům hesla, tak s vysokou pravděpodobností je ve stejné tabulce i salt. U Blowfish hashe je pak salt přímo v řetězci hashe. jedinou výhodou budiž to, že při dobrém nastavení cost factoru je brute force útok dost pomalý (v porovnání třeba s útoky na SHA1 nebo MD5) a to ikdyž útočník zná salt.

Pokud použijete Blowfish hash pro ověření hesel na stávajícím systému využívajícím hashovací funkci SHA1 nebo v horším případě pekelnou MD5 apod., tak přechod na Blowfish hash je naprosto jednoduchý a nemusí se ani generovat nová hesla nebo nutit uživatele si je měnit. U nových záznamů se uloží Blowfish hash hesla (salt generován automaticky) a použije se pro ověření klasicky password_verify. U starých hesel se stávající (starý) hash nahradí Blowfish hashem hashe původního – salt se zde v db u těchto záznamů ponechá pro účel verifikace hesla (a bude informovat, že máme použít složitější postup). Hash hesla se zmigruje na novou verzi a přeuloží u uživatelů v db pomocí password_hash(puvodni_hash, PASSWORD_BCRYPT). Ověření po přihlášení u SHA1 (v mém případě původní hash funkce pro uložení hesel) s použitím saltu bude pak u účtů se starým způsobem uložení hesla schématicky password_verify(SHA1(‚mnou zadane heslo‘ .  salt_z_db), blowfish_hash_z_db).

A poznámka na závěr. Na serverech, kde budu tuto změnu implementovat nemám možnost nastavit nové extensions do PHP, proto zde je nejvhodnější volbou bscrypt. Nicméně pokud máte na serveru možnost přidat do PHP extension použijte (díky @spazef0rze za tip) scrypt dostupný jako extension DomBlack / php-scrypt. Pro ty, co přešli (nejspíše z donucení :-)) na Zend framework 2.x je možné použít zendframework / Component_ZendCrypt.

Leave a comment

Your comment