Wachtwoord hashen
Ik heb een registratieformulier aangemaakt, en gebruikers kunnen hun gebruikersnaam en wachtwoord gewoon opgeven. En deze worden dan in de mysql database opgeslagen.
Ik gebruik niet meer dan volgende regel hiervoor.
mysql_query("INSERT INTO users (username, password) VALUES ('$username','$password')");
Maar de wachtwoorden worden gewoon als tekst opgeslagen in mijn mysql tabel(varchar). Hoe kan ik dit beter beveiligen zodat het wachtwoord gehashed word. En hoe unhash in het terug zodat ze nog wel steeds kunnen aanmelden?
Thanks!
Als iemand zijn/haar wachtwoord verliest moeten ze maar een nieuwe opvragen middels hun e-mail.
Er zijn TIG manieren om wachtwoorden te versleutelen. Afhankelijk van hoe veilig deze moet zijn maak je een keuze. De manier waarop je loginmechanisme werkt en hoe sterk je wachtwoorden moeten zijn dragen ook aan deze veiligheid bij. Tis maar net hoeveel tijd/geld/moeite je hier in wilt steken.
Wat is dan een goede manier om je wachtwoord te versleutelen? Mag iets simpels zijn, maar gewoon zodat iemand die de tabellen uitleest van je database dat ze niet de wachtwoord kunnen lezen?
Je zou MD5() kunnen gebruiken (maar deze is verouderd, ik hoor op de achtergrond nu al het boe-geroep van puristen), of wellicht beter SHA1() (edit: of misschien ook niet meer, leest dit).
En als je PHP-versie nieuwe genoeg is (>= 5.5.0) kun je password_hash gebruiken.
Er zijn waarschijnlijk ook een hoop topics over password hashing in PHP te googlen.
Gewijzigd op 08/03/2015 17:17:20 door Thomas van den Heuvel
Als een gebruiker wil inloggen dan vergelijk je niet meer de paswoorden maar de hashes.
Code (php)
Gewijzigd op 08/03/2015 17:34:40 door Frank Nietbelangrijk
en hoe kunnen gebruikers dan inloggen? Want dan zouden ze hun hash moeten weten vooraleer ze hiermee kunnen inloggen?
Lees mijn laatste post nog eens goed door? ;-)
Nee, je vertaalt hun wachtwoord opnieuw naar de bijbehorende hash. En deze vergelijk je dan met wat opgeslagen is in de database.
oh bedankt hadden gelijktijdig geantwoord :), ik probeer het eens uit :)
Ronnie Peeters op 08/03/2015 17:32:48:
oh bedankt hadden gelijktijdig geantwoord :), ik probeer het eens uit :)
ja dacht ik al dat gebeurt zo vaak!
Fatal error: Call to undefined function password_hash()
http://www.sitepoint.com/hashing-passwords-php-5-5-password-hashing-api/
Lees dat a.u.b.
Je kunt het gebruiken vanaf PHP 5.3.7, tot PHP 5.5.0 moet je wel de password_compat files includen zoals je gelezen hebt.
Lees daarna a.u.b. ook nog http://www.sitepoint.com/series/avoid-the-mysql-extension/
Ik weet dat veel lezen minder leuk klinkt dan wat programmeren, debuggen en een resultaat krijgen waar je een goed gevoel over kan hebben. Maar het geeft een nog beter gevoel wanneer je weet dat je code hebt geschreven die net en veilig is!
Lees dat a.u.b.
Je kunt het gebruiken vanaf PHP 5.3.7, tot PHP 5.5.0 moet je wel de password_compat files includen zoals je gelezen hebt.
Lees daarna a.u.b. ook nog http://www.sitepoint.com/series/avoid-the-mysql-extension/
Ik weet dat veel lezen minder leuk klinkt dan wat programmeren, debuggen en een resultaat krijgen waar je een goed gevoel over kan hebben. Maar het geeft een nog beter gevoel wanneer je weet dat je code hebt geschreven die net en veilig is!
Hmm kan het ook zonder een extra api te installeren? Ik kan namelijk niets op de server zelf veranderen.
Welke PHP versie draai je?
PHP/5.4.17
password_* functies zijn niet beschikbaar, maar zijn toch alleen maar wrapper functies voor functionaliteit die beschikbaar is sinds PHP 5.3.7.
Dus inplaats van password_* functies geschreven in C zul je password_* functies geschreven in PHP moeten gebruiken door een bestand te includen op de pagina's waar je de functies nodig hebt. Zie de notitie over "password_compat" in dat artikel.
Kan het ook met crypt? dat ben ik ook vaak tegengekomen?
https://github.com/ircmaxell/password_compat/blob/master/lib/password.php#L155
Maar laten we beginnen met wat je geprobeerd hebt. Code, foutmeldingen etc.
Oh, en heb je dat artikel doorgenomen? Zo ja, hoe aandachtig?
Het kan ook met crypt. Dat password_compat maakt gebruikt van crypt: Maar laten we beginnen met wat je geprobeerd hebt. Code, foutmeldingen etc.
Oh, en heb je dat artikel doorgenomen? Zo ja, hoe aandachtig?
Gewijzigd op 08/03/2015 19:35:09 door Dos Moonen
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
<?php
$salt = "a:@:ER:$:TFFG:$1234:$$$EaDS:bv:";
$pepper = "15244145464:fdsasfdfdsafdfd:ERDSDE$#$DDSFD:DFDFDAWA@:@$$!!@#:";
mysqli_query($connect,"INSERT INTO users (username, password) VALUES ('".mysqli_real_escape_string($username)."',
'".mysqli_real_escape_string(md5(md5($salt.$_POST['pass'].$pepper)))."'')");
?>
$salt = "a:@:ER:$:TFFG:$1234:$$$EaDS:bv:";
$pepper = "15244145464:fdsasfdfdsafdfd:ERDSDE$#$DDSFD:DFDFDAWA@:@$$!!@#:";
mysqli_query($connect,"INSERT INTO users (username, password) VALUES ('".mysqli_real_escape_string($username)."',
'".mysqli_real_escape_string(md5(md5($salt.$_POST['pass'].$pepper)))."'')");
?>
in principe is dit veilig zat.
Gewijzigd op 08/03/2015 19:43:55 door Eeyk Vd noot
$test = crypt("$password", $hash);
mysql_query("INSERT INTO users (username, password) VALUES ('$username','$test')");
Dit heb ik in mijn registratiepagina staan, zo komt hij wel in onleesbare tekst te staan in de tabel. Maar nu weet ik niet goed hoe ik mijn loginpagina moet aanpassen zodat ik hem daar kan uncrypten.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
session_start();
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
mysql_connect("localhost", "root","usbw") or die(mysql_error());
mysql_select_db("first_db") or die("Cannot connect to database");
$query = mysql_query("SELECT * from users WHERE username='$username'");
$exists = mysql_num_rows($query);
$table_users = "";
$table_password = "";
if($exists > 0) //IF there are no returning rows or no existing username
{
while($row = mysql_fetch_assoc($query))
{
$table_users = $row['username'];
$table_password = $row['password'];
}
if(($username == $table_users) && ($password == $table_password))
{
if($password == $table_password)
{
$_SESSION['user'] = $username;
header("location: home.php");
}
}
else
{
Print '<script>alert("Incorrect Password!");</script>';
Print '<script>window.location.assign("login.php");</script>';
}
}
else
{
Print '<script>alert("Incorrect Username!");</script>';
Print '<script>window.location.assign("login.php");</script>';
}
?>
session_start();
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
mysql_connect("localhost", "root","usbw") or die(mysql_error());
mysql_select_db("first_db") or die("Cannot connect to database");
$query = mysql_query("SELECT * from users WHERE username='$username'");
$exists = mysql_num_rows($query);
$table_users = "";
$table_password = "";
if($exists > 0) //IF there are no returning rows or no existing username
{
while($row = mysql_fetch_assoc($query))
{
$table_users = $row['username'];
$table_password = $row['password'];
}
if(($username == $table_users) && ($password == $table_password))
{
if($password == $table_password)
{
$_SESSION['user'] = $username;
header("location: home.php");
}
}
else
{
Print '<script>alert("Incorrect Password!");</script>';
Print '<script>window.location.assign("login.php");</script>';
}
}
else
{
Print '<script>alert("Incorrect Username!");</script>';
Print '<script>window.location.assign("login.php");</script>';
}
?>
In ieder geval wordt het niet geadviseerd. Ikzelf ben ook een voorstander van password_hash(). Een salt is sowieso een goed idee om 'dictionairy-attacks' tegen te gaan.