WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   Min lösenordslösning (https://www.wn.se/forum/showthread.php?t=27862)

NevYn 2008-03-11 14:18

Hej, har efter mycket om och men kommit fram till följande lösning för att hasha användares lösenord:

Kod:

$pwd = 'användarens lösenord';
$dynsalt1 = 'dynamiskt salt';
$dynsalt2 = 'annat dynamiskt salt';
$pass = base64_encode(hash_hmac,'sha512',$pwd,hash_hmac('sha512',$dynsalt1,$dynsalt2,true),true));

Jag tycker det borde vara en ganska bra lösning, men eftersom jag inte är allvetande kanske det finns någon annan där ute som har några synpunkter?

talthoff 2008-03-11 15:08

http://www.sitic.se/publikationer/na...-losenord-ratt

NevYn 2008-03-11 15:20

Citat:

Originally posted by talthoff@Mar 11 2008, 16:08
http://www.sitic.se/publikationer/na...-losenord-ratt
jo, den har jag läst, och har alltid använt sha1(dymaniskt salt + pwd + statiskt salt) tidigare, men har nu kommit fram till den här lösningen..

länkar:
http://en.wikipedia.org/wiki/HMAC
http://se2.php.net/hash_hmac
http://en.wikipedia.org/wiki/SHA_has...ions#SHA_sizes

efter att ha läst den infon så har jag fått för mig att den här lösningen är säkrare än den förstnämnda? men som sagt, jag är inte allvetande..

eliasson 2008-03-11 16:15

Kod:

md5(salt-på-100-random-chars + användarnamn + lösenord + salt-på-100-random-chars)
Fungerar också jättebra ;-)

gsoc 2008-03-11 17:20

Att sedan skriva ut hur man gör är ju inte så bra om man skall vara petig...

Kristoffer G 2008-03-11 17:25

Här har du en variant på ett login+registrerings system som jag gjort...ett väldigt väldigt simpelt sådan...


register.php
Kod:

<?php
//Kontrollerar om du försöker registrera dig
if(isset($_POST['skicka'])){
include 'inc/connect.php';
include 'inc/functions.php';
 
$in_user * *= $_POST['user'];
$in_pass * *= $_POST['pass'];
$in_check * = $_POST['check'];
 
//Anropar tre funktioner som kontrollerar de inmatade värdena
$check1 = langd($in_user, $in_pass);
$check2 = same($in_pass, $in_check);
$check3 = exists($in_user);
 
//Om allt är ok
if($check1 == "ok"){
if($check2 == "ok"){
if($check3 == "ok"){
 
//Genererar ett slumpat tal
$x = mt_rand(strlen($in_user), 101);
//Anropar frunktioner för att generera hash+salt+multiple runs
$p_hash = password($in_pass, $x);
$salt * = salt();
$fused *= fuse($p_hash, $salt, $x);
 
//Skickar in värdena i databasen
$count = $conn->exec("INSERT INTO Uregister(user, password, salt, x)VALUES('$in_user', '$fused', '$salt', '$x')");
$conn = null;
 
header ("location: register.php?done");
}
}
}
//Skriver ut eventuella felmeddelanden
if($check1 !== "ok"){ echo "$check1<br />";}
if($check2 !== "ok"){ echo "$check2<br />";}
if($check3 !== "ok"){ echo "$check3<br />";}
}
if(isset($_GET['done'])){
echo "Registrering lyckad";
}
?>
<form action="register.php" method="post">
Användarnamn: *<br />
<input type="text" name="user" /> <em>Minst 4 tecken</em><br />
Lösenord: <br />
<input type="password" name="pass" /> <em>Minst 4 tecken</em><br />
Upprepa Lösenord: <br />
<input type="password" name="check" /><br />
<input type="submit" name="skicka" value="Registrera" />
</form>

Login.php
Kod:

<?php
//If-sats som kontrollerar om man försöker logga in
if(isset($_POST['login'])){
include 'inc/connect.php';
include 'inc/functions.php';
 
$in_user = $_POST['user'];
$in_pass = $_POST['pass'];
 
//Hämtar värden från databasen, baserat på användarnamnet
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$do = $conn->prepare("SELECT password, salt, x FROM Uregister WHERE user = :user LIMIT 1");
$do->bindParam(':user', $in_user, PDO::PARAM_STR);
$do->execute();
$obj = $do->fetch(PDO::FETCH_OBJ);
 
$db_pass = $obj->password;
$db_salt = $obj->salt;
$db_x * *= $obj->x;
 
//Anropar funktionerna som behövs föra tt återskapa lösenordet
$gen_pass = password($in_pass, $db_x);
$gen_fuse = fuse($gen_pass, $db_salt, $db_x);
$conn = null;
 
//Kontrollerar om lösenorden matchar
if($gen_fuse == $db_pass){
//Skapar en session med alla uppgifter
session_start();
$_SESSION['user'] * = $in_user;
$_SESSION['pass'] * = $db_pass;
$_SESSION['ip'] * * = $_SERVER['REMOTE_ADDR'];
 
echo "Du är nu inloggad som {$_SESSION['user']}";
}
else{ echo "Fel användarnamn eller lösenord"; }
}
?>
<form action="login.php" method="post">
Användarnamn: *<br />
<input type="text" name="user" /> <em>Minst 4 tecken</em><br />
Lösenord: <br />
<input type="password" name="pass" /> <em>Minst 4 tecken</em><br />
<input type="submit" name="login" value="Login" />
</form>

Funktionerna
Kod:

<?php
//Kontrollerar längden på användarnamn och lösenord
function langd ($var1, $var2){
 * *if(strlen($var1)<4 || strlen($var2) <4){
 * *$error = "*Användarnamnet eller lösenordet är för kort";
 * *}
 * *else {$error = "ok"; }
 * *return $error;
}
 
//Kontrollerar om lösenordet matchar det upprepade lösenordet
function same($var1, $var2){
 * *if($var1 !== $var2){ $error = "*Lösenorden matchar inte"; }
 * *else { $error = "ok"; }
 * *return $error;
}
 
//Kontrollerar om användarnamnet redan existerar
function exists ($var1){
 * *include 'connect.php';
 * *
 * *$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 * *$do= $conn->prepare ("SELECT COUNT(id) as antal FROM Uregister WHERE user = :user ");
 * *$do->bindParam(':user', $var1, PDO::PARAM_INT);
 * *$do->execute();
 * *$obj = $do->fetch(PDO::FETCH_OBJ);
 * *$db_count = $obj->antal;
 * *
 * *if($db_count <1){ $error = "ok"; }
 * *else { $error = "*Det angivna användarnamnet finns redan"; }
 * *$conn = null;
 * *return $error;
}
 
//Hashar lösenordet
function password ($password, $x){
 * *$password = md5($password);
 * *for($i=0; $i <= $runs; $i++){
 * *$password = sha1($password);
 * *}
 * *return $password;
}
 
//Skapar ett salt
function salt (){
 * *$chars = "8!b9yea@of,g5ic¤j2d3k4_l7mhrn%#ps&t6uqvx-.1";
 * *$length = strlen($chars);
 
 * *for($i=0; $i <= $length; $i++){
 * *$runs = mt_rand(0,$length);
 * *$salt .= substr($chars, $runs, 1);
 * *}
 * *return sha1($salt);
}
//Bakar ihop lösenordet och saltet i en loop
function fuse ($password, $salt, $x){
 * *for($i=0; $i <= $runs; $i++){
 * *$fused = sha1("$password @:_:@ $salt");
 * *}
 * *return $fused;
}
?>

Du kan kolla i funktionerna osv hur jag har gjort. Fungerar väldigt bra... men tänk på att salt och x helst inte ska paras tilslammans med lösenordet i databasen.


EDIT*
Såg att jag glömt fixa så att INPUT kör genom prepared... men det ska det.

eliasson 2008-03-11 18:02

Citat:

Originally posted by gsoc@Mar 11 2008, 18:20
Att sedan skriva ut hur man gör är ju inte så bra om man skall vara petig...

Exakt, men dock så publicerar man inte sina salt's som totalt är ~200 garbage-chars ;-)

NevYn 2008-03-11 20:17

Citat:

Originally posted by gsoc@Mar 11 2008, 18:20
Att sedan skriva ut hur man gör är ju inte så bra om man skall vara petig...
Lösningen är något mer komplex än det jag skrivit ut, men det här utgör en del i den.
Mest hashnings-förfarandet jag va ute att få kommentarer på, då jag inte sett många som använt något liknande.

Jonas 2008-03-11 21:58

Varför ens köra Base64 ??? :S

Base64 kännetecknas enkelt på att det OFTAST är 2st likamed tecken på slutet.
Vilket gör det relativt enkelt för hackern när han får tag i dina lösenord och därmed mer eller mindre har lösenordet i klartext.

EN utav nackdelen med base64 är helt enkelt att varje tecken "väger mer".
Citat:

Base64-encoded data takes about 33% more space than the original data.
#EDIT: Notera även att Base64 inte är en hash. Base64 används främst i mailprotokollet för att skicka bilagor.

gsoc 2008-03-11 22:13

Vet inte om det bara är jag men det ser ut som din applikation är väldigt sårbar för sql injections...

register.php
Kod:

$in_user
Login.php
Kod:

$in_user
Sen kan man nog ta $var1 i funktionen exists, men det blir ungefär samma bara det att det är på databas anslutningar man kommer åt...


Alla tider är GMT +2. Klockan är nu 04:16.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson