Hasha det genererade saltet med SHA1
Hasha lösenordet med SHA1
Foga ihop Lösenord+salt och hasha det med SHA1
Blanda gäran md5 och sha1 (eller andra)... du kan även köra med multiple runs (tror det heter så).. vilket innebär att du loop hashar det ihop fogade salt+pass... hur många gånger det ska loopas kan du slumpa fram, och sen sparar du undan slumpvärdet så att du sedan kan kontrollera hur många gånger du ska loopa ett inmatat lösenord med saltet för att kunna matcha det mot lösenordet i databasen.
Har lite bottom nu när jag skriver.. så risken finns att det är dåligt förklarat.
md5 / sha1 är två utmärkta hashing-funktioner :)
Gissar på att Tulork menar ungefär såhär:...
Ah, tackar, den där kommer komma till användning
Men hur gör man på klientsidan? I nuläget md5 krypterar jag den känsliga informationen redan på klientsidan. Någon som har en länk till ett javascript som hashar med sha1 och salt som man får använda utan några licenser?
En liten fotnot bara:
Eftersom javascriptkällan går att se så kan det vara en liiiten säkerhetsrisk eftersom du avslöjar hur du hashar din sträng, så hasha även gärna lite till på serversidan med php också :) Lösenord är som pommes, man kan inte salta för mycket ;)
Har precis skrivit klart ett litet hash+salt+multiple runs scipt till ett eget litet projekt... den som vill får gärna använda eller modifiera scriptet som de själva önskar... om ni förstår mina kommentarer :D
<?php
//Funktion som behandlar lösenordet
function password ($password, $runs){
$password = md5($password);
for($i=0; $i <= $runs; $i++){
$password = sha1($password);
}
return $password;
}
//Funktion som 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);
}
//Funktion som fogar ihop löseordet och saltet i en loop med sha1
function fuse ($password, $salt, $runs){
for($i=0; $i <= $runs; $i++){
$fused = sha1("$password @:_:@ $salt");
}
return $fused;
}
//Det lösenord som ska skyddas
$losenord = "lösenordet";
//Detta slumpar fram ett värde som används för multiple runs.
//SPARAS I DATABASEN
$runs = mt_rand(1,99);
//Skickar lösenordet till funktionen password. Får tilbaka det hashat ett antal gånger.
$gen_losen = password($losenord, $runs);
//Anropar funktionen salt som skickar ett hashat salt.
//SPARAS I DATABASEN
$gen_salt = salt();
//Anropar fuse som bakar ihop salt och löseord och hashar det ett antal gånger
//SPARAS I DATABASEN
$gen_fuse = fuse($gen_losen, $gen_salt, $runs);
//########################################################################################
//Exempel vid inmatat lösenord
//########################################################################################
/*
För att förstå denna del så får ni tänka er att användaren redan är registrerad och att följande värden finns sparade i databasen:
$runs
$gen_salt
$gen_fuse
I delen nedan illustrerar jag hur man återanvänder funktionerna för att generera och matcha ett lösenord som en användare skickat
när dem loggat in.
*/
//$inmatat är variablen vars innehåll är det lösenord som användaren försöker logga in med
//Se till att använda mysql_real_escape_string() eller något annat skydd innan du hämtar värden från databasen
$inmatat = "lösenordet";
//$db_salt är variablen vars innehåll är hämtat från databasen, baserat på exempelvis användarnamnet man matade in vid inloggningen
$db_salt = "salt från databasen";
//$db_runs är variablen vars innehåll är hämtat från databasen, baserat på exempelvis användarnamnet man matade in vid inloggningen
$db_runs = "loopvärdet från databasen";
//Här anropas funktionerna som behövs och vi får tillbaka ett lösenord som sparas i $check_pass.
//Vi kan sedan matcha detta lösenord mot det lösenord som finns i databasen, baserat på exempelvis användarnamnet
//som matades in vid inloggningen
$check_pass = fuse(password($inmatat, $db_runs), $db_salt, $db_runs);
//Här är ett exempel på hur man kan matcha lösenordet
//$databas_losen innehåller det ihop fogade lösenordet och saltet som lagrats i databasen vid registreringen
if($check_pass == $databas_losen){ echo "Grattis!"; }
else{ echo "Ditt lösenord matchade inte!"; }
?>
Ska du ha något skydd på klientsidan är det SSL som gäller. Att tro att man vinner någon som helst säkerhet på att hasha via javascript innan sändning är bara att förvilla sig själv. Om en attackerare avlyssnar trafiken spelar det inte honom någon roll om han får ett lösenord eller en hash då han lika gärna kan göra en replay-attack med ett hash som med ett lösen. Det är lika öppet för intrång alltså.
Om en attackerare avlyssnar trafiken spelar det inte honom någon roll om han får ett lösenord eller en hash då han lika gärna kan göra en replay-attack med ett hash som med ett lösen. Det är lika öppet för intrång alltså.
Eftersom många tyvärr använder samma användarnamn och lösenord lite överallt så kan det vara smått livsfarligt att skicka lösenord i klartext. Om någon lyckas avlyssna din sida så är ju redan loppet kört för Dig, men man kan ju i alla fall hindra att denna illvilliga person ska kunna bygga sig en otäck liten databas med användarnamn med matchande lösenord som kan användas för att ta sig in lite var stans. Även om man avslöjar hur man hashar sitt lösenord genom javascript så blir det inte effektivt att "brute-forca" just för detta ändamål.
Annars håller jag med colione om att SSL är det enda rätta om man vill vara riktigt säker :)