Kaip naudoti „bcrypt“ slaptažodžių maišymui PHP?

Kartais girdžiu patarimą „Naudoti„ Bcrypt “slaptažodžių saugojimui PHP,„ Bcrypt “taisyklės.“

Bet kas yra bcrypt ? PHP nesiūlo tokių funkcijų: Vikipedija kalba apie failų šifravimo įrankį ir žiniatinklio paiešką, ji tik atskleidžia keletą „ Blowfish“ diegimų įvairiomis kalbomis. Dabar „Blowfish“ yra prieinama ir PHP, naudojant „ mcrypt , bet kaip tai padeda saugoti slaptažodžius? Blowfish yra bendrojo pobūdžio šifras, jis veikia dviem būdais. Jei jis gali būti užšifruotas, jis gali būti iššifruotas. Slaptažodžiams reikia vienpusių maišos funkcijų.

Kas yra paaiškinimas?

1151
25 янв. Vilx yra nustatytas - 25 sausis 2011-01-25 18:34 '11, 18:34, 2011-01-25 18:34
@ 9 atsakymai

bcrypt yra maišymo algoritmas, kuris yra suskirstytas į aparatūrą (per pasirinktinį skaičių raundų). Jo lėtumas ir kelios pakopos užtikrina, kad užpuolikas turi įdiegti didžiulius įrankius ir įrangą, kad sugadintų jūsų slaptažodžius. Įtraukite druskos slaptažodį į šį bcrypt ( bcrypt druską), ir jūs galite būti tikri, kad užpuolimas beveik neįmanomas be juokingų lėšų ar techninės įrangos.

bcrypt naudoja „Eksblowfish“ maišos slaptažodžio algoritmą. Nors „Eksblowfish“ ir „Blowfish“ šifravimo etapas yra lygiai toks pats, pagrindinis „Eksblowfish“ tvarkaraščio etapas užtikrina, kad bet kuri vėlesnė būsena priklauso ir nuo druskos, ir nuo raktų (vartotojo slaptažodžio), ir jokia būsena negali būti iš anksto apskaičiuota nežinant abiejų. Dėl šio bcrypt skirtumo bcrypt yra vienpusis maišos algoritmas. Jūs negalite gauti paprasto teksto slaptažodžio nežinant druskos, turų ir (slaptažodžio) klavišo , [ Šaltinis ]

Kaip naudoti „bcrypt“:

Naudojant PHP> = 5,5-DEV

Slaptažodžio keitimo funkcijos dabar yra sukurtos tiesiogiai PHP> = 5.5 . Dabar galite naudoti password_hash() kad sukurtumėte bet kurio slaptažodžio bcrypt maišą:

 <?php // Usage 1: echo password_hash('rasmuslerdorf', PASSWORD_DEFAULT)."\n"; // $2y$10$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx // For example: // $2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a // Usage 2: $options = [ 'cost' => 11 ]; echo password_hash('rasmuslerdorf', PASSWORD_BCRYPT, $options)."\n"; // $2y$11$6DP.V0nO7YI3iSki4qog6OQI5eiO6Jnjsqg7vdnb.JgGIsxniOn4C 

Jei norite patikrinti naudotojo pateiktą slaptažodį esamam maišui, galite naudoti password_verify() :

 <?php // See the password_hash() example to see where this came from. $hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq'; if (password_verify('rasmuslerdorf', $hash)) { echo 'Password is valid!'; } else { echo 'Invalid password.'; } 

Naudojant PHP> = 5.3.7, <5.5-DEV (taip pat ir RedHat PHP> = 5.3.3)

Yra „ GitHub“ suderinamumo biblioteka, pagrįsta pirmiau minėtų funkcijų šaltiniu, kuris iš pradžių buvo parašytas C, kuris suteikia tokį patį funkcionalumą. Įdiegus suderinamumo biblioteką, naudojimas bus toks pat, kaip aukščiau (atėmus sutrumpinto masyvo pavadinimą, jei vis dar esate 5.3.x skyriuje).

Naudojant PHP <5.3.7 (DEPRECATED)

Galite naudoti kriptavimo crypt() funkciją, kad sukurtumėte įvesties eilutės bcrypt hash. Ši klasė gali automatiškai generuoti druskas ir tikrinti esamas rūkas kaip įėjimus. Jei naudojate didesnę ar lygią 5.3.7 PHP versiją, labai rekomenduojama naudoti integruotą funkciją arba suderinamumo biblioteką . Ši alternatyva teikiama tik istoriniais tikslais.

 class Bcrypt{ private $rounds; public function __construct($rounds = 12) { if (CRYPT_BLOWFISH != 1) { throw new Exception("bcrypt not supported in this installation. See http://php.net/crypt"); } $this->rounds = $rounds; } public function hash($input){ $hash = crypt($input, $this->getSalt()); if (strlen($hash) > 13) return $hash; return false; } public function verify($input, $existingHash){ $hash = crypt($input, $existingHash); return $hash === $existingHash; } private function getSalt(){ $salt = sprintf('$2a$%02d$', $this->rounds); $bytes = $this->getRandomBytes(16); $salt .= $this->encodeBytes($bytes); return $salt; } private $randomState; private function getRandomBytes($count){ $bytes = ''; if (function_exists('openssl_random_pseudo_bytes')  (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) { // OpenSSL is slow on Windows $bytes = openssl_random_pseudo_bytes($count); } if ($bytes === ''  is_readable('/dev/urandom')  ($hRand = @fopen('/dev/urandom', 'rb')) !== FALSE) { $bytes = fread($hRand, $count); fclose($hRand); } if (strlen($bytes) < $count) { $bytes = ''; if ($this->randomState === null) { $this->randomState = microtime(); if (function_exists('getmypid')) { $this->randomState .= getmypid(); } } for ($i = 0; $i < $count; $i += 16) { $this->randomState = md5(microtime() . $this->randomState); if (PHP_VERSION >= '5') { $bytes .= md5($this->randomState, true); } else { $bytes .= pack('H*', md5($this->randomState)); } } $bytes = substr($bytes, 0, $count); } return $bytes; } private function encodeBytes($input){ // The following is code from the PHP Password Hashing Framework $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; $output = ''; $i = 0; do { $c1 = ord($input[$i++]); $output .= $itoa64[$c1 >> 2]; $c1 = ($c1  0x03) << 4; if ($i >= 16) { $output .= $itoa64[$c1]; break; } $c2 = ord($input[$i++]); $c1 |= $c2 >> 4; $output .= $itoa64[$c1]; $c1 = ($c2  0x0f) << 2; $c2 = ord($input[$i++]); $c1 |= $c2 >> 6; $output .= $itoa64[$c1]; $output .= $itoa64[$c2  0x3f]; } while (true); return $output; } } 

Šį kodą galite naudoti taip:

 $bcrypt = new Bcrypt(15); $hash = $bcrypt->hash('password'); $isGood = $bcrypt->verify('password', $hash); 

Taip pat galite naudoti „ Portable PHP Hashing Framework“ .

976
14 июня '11 в 1:11 2011-06-14 01:11 atsakymą pateikė Andrew Moore , birželio 14 d. 11, 11:11 2011-06-14 01:11

Taigi norite naudoti „bcrypt“? Nuostabus! Tačiau, kaip ir kitose kriptografijos srityse, jūs neturite to daryti patys. Jei jums reikia nerimauti kažką panašaus į raktų tvarkymą arba saugoti druskas arba generuoti atsitiktinius numerius, jūs esate neteisingas.

Priežastis yra paprasta: tai taip trivialiai lengva sunaikinti bcrypt . Tiesą sakant, jei pažvelgsite į beveik kiekvieną šio puslapio kodą, pastebėsite, kad ji pažeidžia bent vieną iš šių bendrų problemų.

Veidas, kriptografija yra sudėtinga.

Palikite tai ekspertams. Palikite ją žmonėms, kurie dirba, kad palaikytų šias bibliotekas. Jei reikia priimti sprendimą, tai darote neteisingai.

Vietoj to, tiesiog naudokite biblioteką. Kai kurie iš jų egzistuoja priklausomai nuo jūsų reikalavimų.

Bibliotekos

Toliau pateikiamas kai kurių dažniausiai naudojamų API suskirstymas.

PHP 5,5 API - (galima 5.3.7 +)

Pradedant nuo PHP 5.5, įvedama nauja slaptažodžio keitimo API. Taip pat yra suderinamumo blokelių biblioteka, kurią palaiko (5.3). Jis gali būti peržiūrėtas ir lengvai naudojamas.

 function register($username, $password) { $hash = password_hash($password, PASSWORD_BCRYPT); save($username, $hash); } function login($username, $password) { $hash = loadHashByUsername($username); if (password_verify($password, $hash)) { //login } else { // failure } } 

Iš tiesų, tai buvo labai paprasta.

Ištekliai

„Zend“ „Kriptografija“ Slaptažodžio kodavimas (5.3.2 +)

Tai dar viena API, panaši į PHP 5.5, ir sukuria panašų tikslą.

 function register($username, $password) { $bcrypt = new Zend\Crypt\Password\Bcrypt(); $hash = $bcrypt->create($password); save($user, $hash); } function login($username, $password) { $hash = loadHashByUsername($username); $bcrypt = new Zend\Crypt\Password\Bcrypt(); if ($bcrypt->verify($password, $hash)) { //login } else { // failure } } 

Ištekliai

PasswordLib

Tai šiek tiek kitoks požiūris į slaptažodį. Vietoj to, kad palaikytų „bcrypt“, „PasswordLib“ palaiko daugybę maišymo algoritmų. Tai dažniausiai naudinga kontekste, kur jums reikia išlaikyti suderinamumą su paveldėtomis ir suskaidytomis sistemomis, kurios gali būti nevaldomos. Jis palaiko daugybę maišymo algoritmų. Ir palaiko 5.3.2 +

 function register($username, $password) { $lib = new PasswordLib\PasswordLib(); $hash = $lib->createPasswordHash($password, '$2y$', array('cost' => 12)); save($user, $hash); } function login($username, $password) { $hash = loadHashByUsername($username); $lib = new PasswordLib\PasswordLib(); if ($lib->verifyPasswordHash($password, $hash)) { //login } else { // failure } } 

Literatūra:

  • Šaltinio kodas / dokumentacija: GitHub

Perėjimas

Tai sluoksnis, kuris palaiko „bcrypt“, bet taip pat palaiko gana stiprų algoritmą, kuris yra naudingas, jei neturite prieigos prie PHP> = 5.3.2 ... Jis iš tikrųjų palaiko PHP 3.0+ (nors ir ne su „bcrypt“).

 function register($username, $password) { $phpass = new PasswordHash(12, false); $hash = $phpass->HashPassword($password); save($user, $hash); } function login($username, $password) { $hash = loadHashByUsername($username); $phpass = new PasswordHash(12, false); if ($phpass->CheckPassword($password, $hash)) { //login } else { // failure } } 

Ištekliai

Pastaba . Nenaudokite PHPASS alternatyvų, kurios nėra talpinamos atvirame kampe, tai yra skirtingi projektai.

Apie BCrypt

Jei pastebėsite, kiekviena iš šių bibliotekų grąžins vieną eilutę. Taip yra dėl to, kaip BCrypt veikia viduje. Ir ten yra TON atsakymų. Čia yra pasirinkimas, kurį parašiau, kad čia nesuskaičiuos / įklijuosiu, bet nurodykite:

Užverti

Yra daug įvairių variantų. Kuris iš jūsų pasirinksite. Tačiau aš labai rekomenduoju naudoti vieną iš pirmiau minėtų bibliotekų, kad galėtumėte tai tvarkyti.

Vėlgi, jei tiesiogiai naudojate crypt() , tikriausiai darote kažką neteisingo. Jei jūsų kodas naudoja hash() (arba md5() arba sha1() ) tiesiogiai, beveik neabejotinai darote kažką neteisingo.

Tiesiog naudokite biblioteką ...

275
12 июня '13 в 22:23 2013-06-12 22:23 atsakymas pateikiamas ircmaxell birželio 12 d. 13 val. 22:23 2013-06-12 22:23

Enough with Rainbow“ lentelėse gausite daug informacijos : ką reikia žinoti apie saugias slaptažodžių schemas arba „ Portable PHP password hashing“ .

Tikslas yra sušvelninti slaptažodį su kažkuo lėtai, taigi kažkas, kas gauna jūsų slaptažodžio duomenų bazę, mirs bandydamas jį pernelyg apsunkinti (10 ms vėlavimas tikrinti slaptažodį nėra jums nieko, daug kas bando išsiaiškinti Tai). „Bcrypt“ yra lėtas ir gali būti naudojamas su parametru, kad būtų galima pasirinkti, kiek jis yra lėtas.

43
25 янв. atsakymas pateikiamas Arkh 25 jan. 2011-01-25 18:46 '11, 18:46, 2011-01-25 18:46

Galite sukurti vienpusį maišą su „bcrypt“ naudojant „PHP crypt() funkciją ir perduoti atitinkamą „Blowfish“ druską. Svarbiausia iš visos lygties yra tai, kad A) algoritmas nebuvo pažeistas, ir B) jūs teisingai išsiskyrėte kiekvieną slaptažodį . Nenaudokite druskos visam naudojimui; kuri atveria visą jūsų paraišką atakuoti iš vienos lentelės rinkinio Rainbow.

PHP - kripto funkcija

34
25 янв. atsakymas suteiktas coreyward sausio 25 2011-01-25 18:48 '11, 18:48, 2011-01-25 18:48

Pakeisti: 2013.01.15. Jei jūsų serveris jį palaikys, naudokite martinstoeckli sprendimą .


Kiekvienas nori, kad jis taptų sunkesnis, nei yra. Kripto () funkcija atlieka didžiąją dalį darbo.

 function blowfishCrypt($password,$cost) { $chars='./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; $salt=sprintf('$2y$%02d$',$cost); //For PHP < PHP 5.3.7 use this instead // $salt=sprintf('$2a$%02d$',$cost); //Create a 22 character salt -edit- 2013.01.15 - replaced rand with mt_rand mt_srand(); for($i=0;$i<22;$i++) $salt.=$chars[mt_rand(0,63)]; return crypt($password,$salt); } 

Pavyzdys:

 $hash=blowfishCrypt('password',10); //This creates the hash $hash=blowfishCrypt('password',12); //This creates a more secure hash if(crypt('password',$hash)==$hash){  } //This checks a password 

Žinau, kad tai turėtų būti akivaizdi, tačiau nenaudokite slaptažodžio.

32
31 окт. Jon Hulka atsakymas, spalio 31 d. 2012-10-31 11:25 '12, 11:25 am 2012-10-31 11:25

5.5 versija „PHP“ turės integruotą paramą „BCrypt“, „ password_hash() ir password_verify() funkcijoms. Tiesą sakant, tai yra tik apvalkalai aplink crypt() funkciją ir supaprastina jo naudojimą. Ji rūpinasi saugios atsitiktinės druskos sukūrimu ir užtikrina gerus numatytuosius nustatymus.

Lengviausias būdas naudoti šias funkcijas yra:

 $hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT); $isPasswordCorrect = password_verify($password, $existingHashFromDb); 

Šis kodas bus „hash“ slaptažodis naudojant „BCrypt“ ( 2y algoritmas), generuoja atsitiktinę druską iš atsitiktinio OS šaltinio ir naudoja numatytąjį išlaidų parametrą (šiuo metu jis yra 10). Antroje eilutėje tikrinama, ar vartotojo įvestas slaptažodis atitinka jau saugomą maišos reikšmę.

Jei norite pakeisti išlaidų parametrą, galite tai padaryti padidindami sąnaudų parametrą 1, padvigubindami laiką, reikalingą maišos vertei apskaičiuoti:

 $hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 11)); 

Skirtingai nuo "cost" parametro, geriau palikti "salt" parametrą, nes funkcija jau daro viską, kas įmanoma, kad būtų sukurta kriptografiškai saugi druska.

PHP versijoje 5.3.7 ir vėlesnėje versijoje yra to paties autoriaus suderinamumo paketas, kuris sukūrė password_hash() . PHP versijoms iki 5.3.7, crypt() su 2y , unicode saugus BCrypt algoritmas nepalaikomas. Vietoj to, galite pakeisti 2a , kuri yra geresnė alternatyva ankstesnėms PHP versijoms.

24
11 янв. atsakymas duotas martinstoeckli 11 sausis 2013-01-11 11:07 '13, 11:07, 2013-01-11 11:07

Alternatyva yra naudoti „scrypt“, specialiai suprojektuotą peržengti „Colin Percival“ bcrypt iššifruojant „PHP“ išplėtimą „PECL“ . Idealiu atveju šis algoritmas bus išverstas į PHP, kad jį būtų galima nurodyti slaptažodžio * funkcijoms (idealiu atveju, kaip „PASSWORD_SCRYPT“), tačiau tai dar nėra.

5
19 февр. Atsakymas pateikiamas „ Synchro“ 19 vas. 2014-02-19 17:17 '14, 17:17, 2014-02-19 17:17

Dabartinis mąstymas: maišos turėtų būti lėtiausios, o ne greičiausios. Tai slopina vaivorykštės išpuolius.

Taip pat prijungtas, bet atsargiai: užpuolikas neturėtų turėti neribotos prieigos prie prisijungimo ekrano. Norėdami to išvengti: nustatykite IP adreso stebėjimo lentelę, kurioje kiekvienas paspaudimas įrašomas su URI. Jei per penkias minutes per tą patį IP adresą gaunami daugiau nei 5 prisijungimo bandymai, užblokuokite paaiškinimą. Antrinis požiūris yra turėti dviejų lygių slaptažodžių schemą, pavyzdžiui, bankus. Užraktas, skirtas antrojo leidimo gedimams, pagerina saugumą.

Santrauka: sulėtinkite užpuoliklį naudodami ilgai veikiančias hash funkcijas. Be to, užblokuokite pernelyg daug prieigos prie prisijungimo ir pridėkite antrą slaptažodį.

4
07 дек. Atsakymas pateikiamas FYA 07 dec. 2011-12-07 23:56 '11, 23:56, 2011-12-07 23:56

OAuth 2“ slaptažodžiams :

 $bcrypt = new \Zend\Crypt\Password\Bcrypt; $bcrypt->create("youpasswordhere", 10) 
2
25 марта '16 в 19:55 2016-03-25 19:55 atsakymą pateikė Shemeer M Ali , kovo 25 d. 16, 19:55 2016-03-25 19:55