Autor Zpráva
midlan
Profil
Ahoj,
shlédl jsem přednášku o šifrování hesel webových aplikací. Zkráceně v ní popisuje, že není bezpečné ukládat do databáze šifrovaná hesla algoritmy md5 a sha1, protože existují jejich obrovské databáze, nástroje pro jejich louskání (i se solí) a jsou navržené tak, aby byly rychlé (útočník pak může rychle vytvářet hashe). Všechno řekl dává smysl, jen na konci doporučuje použít algoritmus blowfish. Blowfish je ale symetrická šifra, to znamená, že pomocí klíče se můžu dostat k původnímu textu. Znamená to tedy, že když použiju v php funkci crypt, tak z toho "saltu" co ta funkce dává před vytvořený hash je možné získat i původní text?
Jan Tvrdík
Profil
midlan:
Je noc a nechce se mi to dohledávat, ale mám dojem že je víc věcí označovaných jako blowfish. To, co popisuje v přednášce Michal Špaček, rozhodně není symetrická funkce a tedy není možné získat zpět původní text.
Alphard
Profil
Jak to mají vnitřně implementované by šlo hledat ve zdrojácích, ale Michal Špaček mluví o funkci crypt(), u které manuál hned na prvním řádku říká „One-way string hashing“. Takže získat původní string takto zahashovaného hesla nelze.

Pokud by byl zájem zpětně dešifrovat text, je to možné, jsou dohledatelné návody, ale ne funkcí crypt().
midlan
Profil
Jan Tvrdík:
ale mám dojem že je víc věcí označovaných jako blowfish
Je to možné, on tam pořád střídá názvy bcrypt a blowfish.

Alphard:
manuál hned na prvním řádku říká ‚One-way string hashing‘. Takže získat původní string takto zahashovaného hesla nelze.
Jan Tvrdík:
rozhodně není symetrická funkce a tedy není možné získat zpět původní text.
Nejspíš máte oba pravdu, kdyby to bylo reverzní někdo by si toho snad za tu dobu všiml a nahlásil to :)

Ještě tam zmiňuje, že tahle funkce funguje správně až od verze 5.3.7 a v changelogu stojí:

5.3.7 Added $2x$ and $2y$ Blowfish modes to deal with potential high-bit attacks.

Co to znamená? Jaký algritmus tedy požívat, 2a, 2x nebo 2y?
Alphard
Profil
V nižších verzích byly nějaké problémy s ne-ASCII znaky, proto ty změny.
Když s tímto hashem nyní začínáte (není třeba řešit zpětnou kompatibilitu) a předpokládám nové verze PHP, měl byste preferovat $2y$.
midlan
Profil
Alphard:
Díky za vysvětlení.
měl byste preferovat $2y$
Rozdíl mezi 2x a 2y je tedy jaký?
Jan Tvrdík
Profil
midlan:
Rozdíl mezi 2x a 2y je tedy jaký?
Viz www.php.net/security/crypt_blowfish.php pro podrobnosti.
Davex
Profil
Není Blowfish jako Blowfish. Blowfish hash v PHP je ve skutečnosti implementace hašovací funkce bcrypt, která byla od Blowfish šifry odvozena, takže to není plnohodnotné šifrování.

Po zahašování nelze původní text nikdy získat stejně jako nejde z karbanátku zrekonstruovat původní krávu.
Alphard
Profil
Knihovna password_compat (zmíněná i na videu) implementuje funkce dostupné od PHP 5.5 již pro verze od PHP 5.3.7.
Jejím začleněním lze používat především password_hash() a password_verify, což značně zjednoduššuje použití výše uvedených algoritmů.

 <?php

 # https://github.com/ircmaxell/password_compat
require "password.php";

// zakladni test
$hash = password_hash('djpw', PASSWORD_DEFAULT);

$ch1 = password_verify('djpw', $hash);
$ch2 = password_verify('diskuse', $hash);

var_dump($hash, $ch1, $ch2);
/*
    string '$2y$10$wLMNepLFlrNQ/UgNrs1xFuKYagXFYviiqhvY98vF6nMA1cN4RlK6.' (length=60)
    boolean true
    boolean false
*/

// casova narocnost
for ($i = 5; $i <= 20; $i++)
{
    $start = microtime(true);
    $hash = password_hash("djpw", PASSWORD_BCRYPT, ['cost' => $i]);
    echo "$i: time: " . (microtime(true)-$start) . " s, hash: $hash".PHP_EOL;
}

/*
    5: time: 0.003770112991333 s, hash: $2y$05$V8jpuSf3/Rm.C6n2Z7idH.gX3EgLn5yS0bXNeTSMkQy/fSBwbPxF.
    6: time: 0.0068418979644775 s, hash: $2y$06$X0IqyOO83Vk71/NQtPiWI.xaJZ3Q96RQHIB4dHo2IJ40CdL2qIIwW
    7: time: 0.01375412940979 s, hash: $2y$07$8Ughbpbb2EP6cwMAVl/fNudgIOWeh4kURxC8V7umoId.7N.BzkmqG
    8: time: 0.027801990509033 s, hash: $2y$08$JcSxA4ySB5O94iEMM7c0B.0w3Y0WQm4j/YFrTqJaoq9z5kGyhILAe
    9: time: 0.055742025375366 s, hash: $2y$09$.qljbXAkHUwZIKM6L01RmugbOk2Jqud1QxotNUoQu1FZICDazk9Ay
    10: time: 0.10826110839844 s, hash: $2y$10$kY4t5dHwrzfKvydr.H048.FQ1u0uqbaMYf7vQnBLjdXKTKyhsgJwe
    11: time: 0.21718001365662 s, hash: $2y$11$Y.HPZmi9hP/Bsw4PGcSQfO1Za5yie7G3rteAUTsa33zRQyRnTUn32
    12: time: 0.42345309257507 s, hash: $2y$12$RUGpdF2os2EQWcXIj891zudwdm30rOr4BWSlMgZKsyL2RNkawblCK
    13: time: 0.85921812057495 s, hash: $2y$13$fM7DZtWLPY1Jle9Kbw/kV.XZL8.99AHjlrPpawPhIeE9lfzvpkbkK
    14: time: 1.711776971817 s, hash: $2y$14$WLlIwuCXnLAx4WPIeTBsbeakfe11M/9fAmpsy4vzEtM6MGUmncSPu
    15: time: 3.4192779064178 s, hash: $2y$15$PlDHOX6/10jWjE9I5U54OeDxBDQF8I8DFyf.fQfhyzAlddZPY3KYC
    16: time: 6.9072730541229 s, hash: $2y$16$6eaNfyYLnEMIyg4oD4L9j./ofMY0a7XC7OOoxPiYm6Bb6CGB/.JLu
    17: time: 13.878032922745 s, hash: $2y$17$4oeupFrV6TB38yIcQTz8MecMyy.8j1it0i9UYSnaU.uJKs1URbCsC
    18: time: 27.624588012695 s, hash: $2y$18$mGxG9/Vrves8TaYt6lrcmu09JIJd3ydmCBY9yt6uaHCNLIgs287Yy
    19: time: 55.018815994263 s, hash: $2y$19$U52MfkWu8aZTSEEFTDItUuJprW5dFtvHdyF.iOgz391V0u2tJFGPG
    20: time: 110.68904709816 s, hash: $2y$20$9C/PUsCPvTHEkE8ZFDTOOeivwcf1itXnsDxgO3Hpf8.y4DI2u9viq
*/

Uvedené výsledky jsou z mého počítače. Server je cca o třetinu rychlejší:
  10: time: 0.062798976898193 s, hash: $2y$10$Hxg/bPhHD5C7ZQo7eha45uWaIx8IL7/cZ1zbCLKHt6wu.hdtmKlQO
  11: time: 0.12411499023438 s, hash: $2y$11$eD5a7glmRYibDLtA00s/2ODNxC0GTR8KJ.UrUpK153qcq8VGBhb1G
  12: time: 0.24773597717285 s, hash: $2y$12$YSM.lLkFwhxwyKMeLJxHMejNnX/JKscqkY1NU5SzmkNLaQSp1ad2e
  13: time: 0.49565815925598 s, hash: $2y$13$Mx9QvYQnQXzS0Gs/56Xhgu5q8m2ujN0gALDpVhJxQH/zB2j9igiLG
  14: time: 0.99071192741394 s, hash: $2y$14$0k4coA9QPx0jQ3AWHQdSzuHmFhq0jGc.Qo065Nrsf52vnAbeLYa2S
  15: time: 1.9808959960938 s, hash: $2y$15$RnmSQzo.sIX6eoZnDqS8buK58s3FEgRWjSPzTomERGKUPbIF18NAm
  16: time: 3.9758191108704 s, hash: $2y$16$AbZ3d.XBU.gYyaAnh7qFWOXLQLcdYJ0nbZhROiDlBw6KB.thb9.li
  17: time: 8.1724648475647 s, hash: $2y$17$ywMvsRqEoH/aeQhngqo7nu2yj5FENv2lKX0O5Rtqcfz8cqE1taTRK
midlan
Profil
Alphard:
Preferuji když jsou funkce, které spolu souvisí v jedné třídě, proto jsem si napsal svoje řešení:
<?php
class Cryptography {
  
  public static function &random($lenght, $stack = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ') {
    $random = '';
    for($stack_length = strlen($stack)-1; $lenght > 0; $lenght--)
      $random .= $stack[mt_rand(0, $stack_length)];
    return $random;
  }
  
  public static function bcryptHash($string, $cost = 12) {
    return crypt($string, sprintf('$2y$%02d$%s$', $cost > 31 ? 31 : ($cost < 4 ? 4 : $cost), self::random(22)));
  }
  
  public static function verify($string, $hash) {
    return crypt($string, $hash) === $hash;
  }
}
Ostatním děkuji za objasnění.
Jan Tvrdík
Profil
midlan:
Preferuji když jsou funkce, které spolu souvisí v jedné třídě, proto jsem si napsal svoje řešení:
To řešení, na které odkazuje Alphard, má úmyslně identické API jako to, které je k dispozici v PHP 5.5. Tvé řešení navíc obsahuje funkci random, která negeneruje kryptograficky bezpečný náhodný řetězec (funkce mt_rand negeneruje dostatečně náhodná čísla, takže lze dopředu se 100% pravděpodobností uhádnout výsledný náhodný řetězec).
midlan
Profil
Jan Tvrdík:
Vím že se jedná o pseudonáhodná čísla, ale počítač opravdové náhodné číslo vytvořit neumí.
Joker
Profil
midlan:
počítač opravdové náhodné číslo vytvořit neumí
Ale je možné z počítače získat náhodná čísla s dostatečnou entropií pro použití v šifrování, v Linuxu třeba z /dev/random.
midlan
Profil
Joker:
v Linuxu třeba z /dev/random
A v PHP? Stejně si myslím, že pro účel vytvoření saltu je to jedno. Salt je stejně celý přístupný v hashi.
Jan Tvrdík
Profil
midlan:
Např. openssl_random_pseudo_bytes (a to jen někdy, viz její druhý parametr). Případně není-li k dispozici, tak je možné použít řešení z Nette.
midlan
Profil
Díky, pužiju jednu z nich.
spaze
Profil
midlan:
Je to možné, on tam pořád střídá názvy bcrypt a blowfish.

Sorry, jdu pozdě. bcryptu se též někdy říká Blowfish hashing. Blowfish je něco jiného než Blowfish hash. A myslím, že existuje i bcrypt, který vlastně není ten bcrypt, o kterém jsem mluvil.

Sorry, já ty názvy nevymýšlel :-)
1Pupik1989
Profil
Já na hesla používám funkci hash, která umí sha512.
spaze
Profil
1Pupik1989: Já na hesla používám funkci hash, která umí sha512.

SHA-512 je pořád příliš rychlá funkce a na ukládání hesel je nevhodná.
juriad
Profil
Nebo, pokud je dostupné PHP 5.5, tak je nejlepší použít http://au2.php.net/password
1Pupik1989
Profil
Nakonec jsem taky proto zůstal u PBKDF2.

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: