Vytvoření zaheashovaného hesla a ošetření solí
- Manny7
- Člen | 67
Mám z tutoriálu z oficiální stránky Nette použitu autentizaci za
pomocí ověření hesla s využitím soli.
Příprava hesla k ověření vypadá nějak takto:
hash_hmac('sha256', $credentials[self::PASSWORD] . $row->salt, $config->hmacKey);
kde
$credentials[self::PASSWORD] . $row->salt je zadané heslo
uživatelem při ověřovacím procesu spojené se solí, která je uložena
v databázi.
$config->hmacKey je bezpečnostní klíč (zb1g7IHt1I)
uložený v config.ini
Já se snažím udělat registraci využívající tento způsob přihlašování, ale trochu bádám, jak to je s tou solí a klíčem… Dočetl jsem se, že při vytváření účtu bych si měl asi vygenerovat nějaký náhodný řetězec o předem stanovené délce, tento řetězec pak uložit do DB spolu s heslem, které uživatel zadá (a to už zakóduji – třeba pomocí MD5tky nebo SHA1). Je to tak?
Jakou roli tam ale hraje pak ten hmacKey? Ten se využívá pak jen při přihlášení a porovnávání údajů? To by pak ale nemělo moc smysl, ne? …nějak nevím jak do toho algoritmu ten hmacKey aplikovat
- LuKo
- Člen | 116
Takto vytvořené heslo je následně ověřeno proti hodnotě z databáze:
<?php
$login = $credentials[self::USERNAME];
$row = \UserModel::getByEmail($login);
$config = Environment::getConfig('security');
$password = hash_hmac('sha256', $credentials[self::PASSWORD] . $row->salt , $config->hmacKey);
if ($row->password !== $password) {
throw new AuthenticationException("Zadali jste nesprávné heslo!", self::INVALID_CREDENTIAL);
}
?>
Z toho tedy vyplývá, že heslo je v databázi uloženo po projití výše
zmíněnou funkcí hash_hmac
a $config->hmacKey
potřebuješ i při registraci.
Editoval LuKo (23. 8. 2010 16:22)
- Blizzy
- Člen | 149
Já tomu rozumím tak, že ten HMAC klíč je (v tomto případě) k posílení hashovací funkce. Také pokud má každá aplikace jiný HMAC klíč, vygeneruje jiný hash i při stejném vstupu a stejné dynamické soli. Sůl generovaná pro uživatele se hodí pro znemožnění použití rainbow tables (v případě znalosti HMAC klíče) a odhalení stejných hesel v případě získání hashů z databáze.
Zatímco HMAC klíč je vždy stejný (v tomto příkladu má roli statické
soli), salt
má každý uživatel vygenerovaný jen pro sebe (je to
dynamická sůl) a uložený v databázi pro pozdější ověřování.
Je potřeba stejným způsobem hashovat heslo při vytváření uživatele jako při ověřování uživatelského hesla.
Editoval Blizzy (23. 8. 2010 16:58)
- Manny7
- Člen | 67
LuKo, Blizzy: jop.. takhle nějak jsem to nakonec dal
dohromady. Ke generování soli zatím používám mt_rand()
,
který mi nageneruje stanovený počet číslic (10)… Ale to asi úplně
ideální není… Asi by bylo lepší vytvořit nějakou množinu prvků
(písmena malé anglické abecedy + číslice) a z této množiny tu sůl
generovat. Přece jen se tím výrazně zmenší riziko dvou stejně
nagenerovaných solí… nebo myslíte, že tohle je už přehnané?
- Blizzy
- Člen | 149
Manny7 napsal(a):
LuKo, Blizzy: jop.. takhle nějak jsem to nakonec dal dohromady. Ke generování soli zatím používám
mt_rand()
, který mi nageneruje stanovený počet číslic (10)… Ale to asi úplně ideální není… Asi by bylo lepší vytvořit nějakou množinu prvků (písmena malé anglické abecedy + číslice) a z této množiny tu sůl generovat. Přece jen se tím výrazně zmenší riziko dvou stejně nagenerovaných solí… nebo myslíte, že tohle je už přehnané?
Ona ta entropie v náhodných číslech je dost veliká, proto bych se toho nebál.
Pokud se bojíš, tak:
- Můžeš přidat jako ingredience pro sůl nejen náhodné číslo, ale i třeba uživatelské jméno nebo budoucí id, pokud ho znáš.
- Můžeš ověřit, že sůl neexistuje, a vygenerovat jinou. Např. nastavíš UNIQUE klíč pro sloupec se solí a databáze ti to zajistí sama.
Pro pevnou délku soli používej hashovací funkci.
Editoval Blizzy (23. 8. 2010 17:08)
- Panda
- Člen | 569
Co použít base_convert
?
base_convert(sha1(uniqid(mt_rand(), TRUE)), 16, 36);
Jinak tyto (tzn. rand
, mt_rand
,
uniqid
) generátory jsou kryptograficky slabé, Jordi Boggiano to
docela dobře popisuje v článku Unpredictable hashes for humans. Pro běžné použití ale
v pohodě stačí.
- Patrik Votoček
- Člen | 2221
Já používám způsob okoukaný myslím z djanga https://github.com/…ies/User.php#L91