nepochopení calculateHash

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Richard Jedlička
Člen | 51
+
0
-

Ahoj,
chtěl bych se zeptat proč je metoda calculateHash v authentikátoru v sandboxu napsaná, tak jak je:

public static function calculateHash($password, $salt = NULL)
{
	if ($password === Strings::upper($password)) { // perhaps caps lock is on
		$password = Strings::lower($password);
	}

	return crypt($password, $salt ?: '$2a$07$' . Strings::random(22)); // proč je tu ta možnost pokud se nazadá $salt, kdy se toho využije??
}

Nějak to nechápu. To co mě hodně zaráží, tak že jako sůl se používá hash hesla uloženého v databázi. A navíc se předpokládá, že zahashování hesla zadaného uživatelem a osolení touto solí se má rovnat opět soli, aby to prošlo:

if ($row->password !== $this->calculateHash($password, $row->password)) {
			throw new Security\AuthenticationException('The password is incorrect.', self::INVALID_CREDENTIAL);
}

Něco mi uniká, nebo jsem něco přehlíd? Prosím vysvětlete mi to.

Dík Uiii

jiri.pudil
Nette Blogger | 1029
+
0
-

To co mě hodně zaráží, tak že jako sůl se používá hash hesla uloženého v databázi. A navíc se předpokládá (…)

Funkce crypt() takhle prostě funguje. Což se ostatně můžeš dočíst v dokumentaci.

proč je tu ta možnost pokud se nazadá $salt, kdy se toho využije??

Když neexistuje původní heslo; takže typicky když vytváříš heslo nové.

Btw bezpečnější než $2a je $2× nebo $2y. Viz tu.

Editoval jiri.pudil (9. 4. 2013 14:57)

nanuqcz
Člen | 822
+
0
-

Mě spíš zaráží to Strings::random(22) – to pak znamená, že metoda calculateHash() vrátí pokaždé něco jiného? Jaký má pak smysl?

jiri.pudil
Nette Blogger | 1029
+
0
-

Je tam ternární operátor. Nový salt se generuje jen tehdy, když metodě calculateHash žádný nepředáš.

nanuqcz
Člen | 822
+
0
-

No právě. Dejme tomu, že registraci uživatele udělám takto:

$db->table('user')->insert(array(
    'login' => $values->login,
    'password' => $authenticator->calculateHash($values->password),  // bez soli
    'role' => 'member',
));

A pak u přihlášení budu ověřovat, jestli jeho heslo sedí:

if ($row->password !== $this->calculateHash($values->password)) {
    throw new AuthenticationException('The password is incorrect.');
}

Protože jsem nepředal sůl, vygeneruje se pokaždé náhodná, a uživatel se nikdy nepřihlásí, protože hash nebude sedět. Jaký to má smysl?

Editoval nanuqcz (9. 4. 2013 15:20)

jiri.pudil
Nette Blogger | 1029
+
0
-

U přihlášení právě předáš původní heslo jako salt:

if ($row->password !== $this->calculateHash($values->password, $row->password)) {
    throw new AuthenticationException('The password is incorrect.');
}
bazo
Člen | 620
+
0
-

tak to nerob a bude to fungovat. crypt() si uklada salt na zaciatok hashu, preto ho musis predavat do calculateHash

nanuqcz
Člen | 822
+
0
-

bazo napsal(a):

tak to nerob a bude to fungovat

Taky že to nedělám, ale když už vznikla tahle diskuze, tak mi zvědavost nedá…

Prostě si nedokážu představit reálnou situaci, kdy to náhodné generování saltu využiju. Takže otázka zůstává – Proč tam ten náhodný salt je?

jiri.pudil
Nette Blogger | 1029
+
0
-

Asi protože

If not provided, the behaviour is defined by the algorithm implementation and can lead to unexpected results.
(http://www.php.net/crypt)

Richard Jedlička
Člen | 51
+
0
-

jiri.pudil: díky, mě je to už jasný.