Pereiti prie turinio

PHP slaptažodžių saugumas


Rekomenduojami pranešimai

Kiekvienam programuotojui neišvengiamai tenka susidurti su vartotojo identifikacijos problema. Tradiciškai lankytojo tapatybės nustatymui naudojama vartotojo vardo ir slaptažodžio kombinacija. Vartotojo vardas ir slaptažodis dažniausiai saugomi duomenų bazėje.

 

Tačiau pradedantiesiems dažnai vis dar iškyla klausimų kaip saugiai išsaugoti slaptažodį. Apžvelkime įvairius būdus, kurie dažnai taikomi saugojant slaptažodžius.

 

Saugojimas taip kaip įvedė vartotojas

 

Įvedus vartotojui savo slaptažodį jis tiesiog išsaugojamas duomenų bazėje tiesiai iš $_POST masyvo. Prisijungimo metu atliekamas palyginimas:

 

Išbandyti veikimą

if ($_POST["password"] == $password) {
 prisijungimas();
} else {
 neteisingai();
}

 

Toks būdas yra labai paprastas ir dažnai pasirenkamas pradedančiųjų programuotojų. Taip pat jei nenorima kurti slaptažodžio pakeitimo modulio, tuomet galima vartotojui lengvai priminti slaptažodį.

 

Tačiau tai yra pats pavojingiausias saugojimo mechanizmas!

 

Dažnai vartotojai naudoja tą patį slaptažodį įvairiuose puslapiuose. Jeigu duomenų bazė bus pavogta įsilaužėlių arba kenkėjų darbuotojų, jūsų klientų tapatybės kituose portaluose gali būti perimtos! Taip nutikus ir šiam faktui išlindus į viešumą jūsų reputacija bus nepataisomai sužlugdyta.

 

Kartais yra manoma, kad duomenų bazė niekada nebus pavogta ir ši problema yra ignoruojama. Tačiau kiekvienais metais net ir didžiausių kompanijų portalai yra kompromituojami ir jų duomenys paviešinami.

 

MD5 hash saugojimas

 

Šį būdą dažniausiai pasirenka pradedantys programuotojai nesenai sužinoję apie slaptažodžių hashing (http://lt.wikipedia.org/wiki/Santraukos_funkcija).

 

Šiuo būdu bet kokio ilgio įvestas slaptažodis konvertuojamas į visuomet tiek pat skaitmenų turintį skaičių. Šis dvejetainis skaičius tuomet konvertuojamas į šešioliktainį skaičių ir jis išsaugojamas kaip simbolių eilutė (angl. string). Jeigu slaptažodis bus visuomet toks pat, tuomet gautas hash rezultatas taip pat bus visuomet toks pat.

 

MD5 yra tiesiog viena iš labiausiai paplitusių hash funkcijų. Šiuo būdu duomenų bazėje niekada nesaugomas vartotojų įvestas slaptažodis, o saugomas tik hash rezultatas. Prisijungimo metu vartotojas įveda savo tikrą slaptažodį, o serverio dalyje jis transformuojamas su MD5 funkcija ir palyginamas su duomenų bazėje esančiu MD5. Jeigu MD5 hash sutampa tuomet vartotojas įvedė tikrai savo slaptažodį.

 

Išbandyti veikimą

 

Į duomenų bazę patalpinama:

$hash = md5($_POST["slaptazodis"]);

 

Prisijungimo metu:

$hash = $vartotojas["hash"];
if (md5($_POST["slaptazodis"]) == $hash) {
 prisijungimas();
} else {
 neteisingai();
}

 

Šis metodas remiasi tuo, kad iš hash rezultato neįmanoma išgauti tikro slaptažodžio. Taip pat hash reikšmė bus unikali ir niekada nebus gauta įvedus kitą slaptažodį.

 

Tačiau MD5 hash funkcija nebėra saugi! Ji yra labai greita ir su šiuolaikinėmis vaizdo plokštėmis galima išbandyti labai daug slaptažodžių itin greitai. Taip pat visos MD5 reikšmės jau suskaičiuotos ir galima atlikti paprastą patikrinimą lentelėje norint sužinoti slaptažodį.

 

Šis metodas yra ne ką saugesnis nei saugojant slaptažodį tokį patį kaip įvedė vartotojas! Naudojant šį būdą jūs rizikuojate savo reputacija.

 

SHA1 hash saugojimas

 

Šis metodas yra panašus kaip ir MD5. Duomenų bazėje taip pat saugojamas tik hash rezultatas gautas su SHA1 funkcija. Tokį metodą naudoja pradedantieji programuotojai, kurie girdėjo, kad MD5 funkcija yra nesaugi.

 

SHA1 hash funkcija sugeneruoja daugiau simbolių turintį rezultatą nei MD5. Tai sumažina tikimybę, kad kitas slaptažodis sugeneruos tokį pat rezultatą.

 

Išbandyti veikimą

 

Tačiau SHA1 funkcija šiuolaikiniais standartais yra pakankamai greita. Praradus duomenų bazę įsilaužėliai gana greitai aptiks tikrus vartotojų slaptažodžius. Daugelis saugumo ekspertų nerekomenduoja naudoti šios funkcijos saugojant slaptažodžius. Naudojant šį būdą jūs rizikuosite savo reputacija!

 

Saugojimas naudojant PHP5.5

 

PHP5.5 versijoje pridėtos slaptažodžių saugojimo ir patikrinimo funkcijos labai su paprastinančios programuotojo darbą. Jos savyje turi pačias naujausias saugumo praktikas. Naudojant šį metodą net ir praradus duomenų bazę jūsų vartotojų slaptažodžiai išliks saugūs. Įsilaužimo atveju jūsų reputacija bus pažeista, tačiau pataisoma.

 

Slaptažodžio saugojimas:

$hash = password_hash($_POST["slaptazodis"], PASSWORD_DEFAULT);

 

Slaptažodžio patikrinimas:

$hash = $vartotojas["hash"];
if (password_verify($_POST["slaptazodis"], $hash)) {
 prisijungimas();
} else {
 neteisingai();
}

 

password_hash() funkcijai perduodamas PASSWORD_DEFAULT parametras nurodo, kad naudoti bcrypt kriptografinį algoritmą. bcrypt buvo sukurtas dabar Google dirbančio Niels Provos ir paremtas Blowfish šifru. bcrypt priklauso "key derivation" funkcijoms ir yra skirtas saugoti slaptažodžiams.

 

Bcrypt rezultatas atrodo šitaip: "$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a"

Pradžioje esantis "$2y$10$" nurodo bcrypt versiją ($2y) ir cost ($10$). Cost nurodo kiek kartų reikia kartoti funkciją (10 reiškia kartoti 2^10 kartų).

 

Taip pat bcrypt algoritmas savyje inkorporuoja "salt" mechanizmą. Salt sugeneruojamas atsitiktinai ir pridedamas kartu į bcrypt rezultatą. Algoritmo vykdymo metu visuomet panaudojama salt reikšmė. Kiekvienas bcrypt rezultatas turi turėti skirtingą salt. Tai išsprendžia problemą, kuri dažnai sutinkama MD5 ir SHA1 algoritmuose, dar kitaip vadinamą Rainbow tables attack. Tai reiškia, kad esant net ir tam pačiam slaptažodžiui su bcrypt rezultatas bus skirtingas kiekvienam vartotojui. Įsilaužėliai turės kiekvieno vartotojo slaptažodį spėti iš naujo.

 

Tikimybė, kad bcrypt rezultatas bus neunikalus yra labai maža. Taip pat šios funkcijos cost parametras užtikrina, kad rezultato gavimas bus lėtas. Įsilaužėliams atspėti slaptažodžius pasinaudojant serverių fermomis bus labai sunku.

 

Rekomenduojama parinkti cost parametrą tokį, kad vieno bcrypt rezultato gavimas jūsų serveryje užtruktų 100 ms. Surasti tinkamą cost parametrą galite šitaip:

<?php
$timeTarget = 0.1; // 100 milliseconds 

$cost = 8;
do {
   $cost++;
   $start = microtime(true);
   password_hash("test", PASSWORD_BCRYPT, ["cost" => $cost]);
   $end = microtime(true);
} while (($end - $start) < $timeTarget);

echo "Cost parametras: " . $cost . "\n";
?>

 

Perduoti cost parametrą:

$hash = password_hash($_POST["slaptazodis"], PASSWORD_BCRYPT, array("cost" => 10));

 

Jeigu slaptažodžius saugosite šiuo būdu, jūsų reputacija bus saugi.

 

Saugojimas naudojant PHP5.3.7+

 

Būdas yra identiškas PHP5.5, tačiau tinka ir senesnėms PHP versijoms.

Panaudoję šią biblioteką pasinaudosite tomis pačiomis funkcijomis:

https://github.com/ircmaxell/password_compat

 

Vartotojų identifikacija naudojant Laravel 4.2

 

Jei esate Laravel framework naudotojas saugus vartotojų valdymas yra itin paprastas.

 

Slaptažodžio saugojimas:

$password = Hash::make(Input::get('slaptazodis'));

 

Vartotojo prisijungimas:

$username = Input::get('vartotojas');
$password = Input::get('slaptazodis');
if (Auth::attempt(array('username' => $username, 'password' => $password))) {
 prisijungimas();
} else {
 neteisingai();
}

 

Išvados

 

Jeigu norima užtikrinti savo klientų duomenų saugumą tuomet privaloma naudoti saugius slaptažodžių saugojimo būdus. To neatlikus jūs rizikuojate savo reputacija. Patirtis rodo, kad praradus reputaciją ją susigrąžinti klientų akyse yra labai sunku.

 

Taigi jeigu rašote savo aplikaciją naudokite PHP5.5 funkcijas password_verify() ir password_hash(). Jeigu naudojate Laravel pasinaudokite siūlomais vartotojų identifikavimo mechanizmais.

 

Sėkmės kuriant saugias aplikacijas!

 

Blogas

Redagavo ManoDebesis
Nuoroda į pranešimą
Dalintis kituose puslapiuose

what about bcrypt? ta prasme galėtai daugiau info apie tai parašyt. Kad pvz tai neatkoduojama ir pan, sudomins daug ką

 

hash'u (message digest), nesvarbu su kokiu algoritmu jie padaryti, neimanoma atokoduoti. Kad atkoduot (decrypt), pirma reikia uzkoduot (encrypt). Hash'as tai tiesiog 'unikalus' identifikatorius, kuris isgaunamas apdorojus turimus duomenis su tam specializuotais algoritmais.

 

bcrypt tiesiog yra mandras tuom, kad jis automatiskai sukuria salt'a ir naudoja kelis ciklus, kad sugeneruoti hash'a (ta pati galima pasiekti ir su kitais algoritmais, kaip pvz. SHA**, taciau tai reikalaus daugiau kodo). Ir nesvarbu, ar slaptazodis buvo hash'intas su bcrypt, ar SHA ar dar kokiu kitu algoritmu, ji teoriskai galima atrasti, taciau praktiskai tai truks per daug laiko.

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Prisijunkite prie diskusijos

Jūs galite rašyti dabar, o registruotis vėliau. Jeigu turite paskyrą, prisijunkite dabar, kad rašytumėte iš savo paskyros.

Svečias
Parašykite atsakymą...

×   Įdėta kaip raiškusis tekstas.   Atkurti formatavimą

  Only 75 emoji are allowed.

×   Nuorodos turinys įdėtas automatiškai.   Rodyti kaip įprastą nuorodą

×   Jūsų anksčiau įrašytas turinys buvo atkurtas.   Išvalyti redaktorių

×   You cannot paste images directly. Upload or insert images from URL.

Įkraunama...
  • Dabar naršo   0 narių

    Nei vienas registruotas narys šiuo metu nežiūri šio puslapio.

×
×
  • Pasirinkite naujai kuriamo turinio tipą...