WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   Hash + salt av lösenord (https://www.wn.se/forum/showthread.php?t=30777)

tartareandesire 2008-07-27 23:18

När det gäller lösenordslagring så har det redan diskuterats en del på WN men jag kunde inte hitta något om lämplig längd att salta sin hashade sträng med? Nu vill jag inte tala om vilka längder jag själv använder eftersom det inte gynnar ändamålet så att säga.

dimka 2008-07-27 23:30

Jag tycker att osCommerce funktion att kryptera lösenord är bäst!

Citat:


function encrypt_password($plain) {

$password = '';

for ($i=0; $i<10; $i++) {
$password .= tep_rand();
// tep_rand() returnerar ett slumpvis tioställigt numeriskt värde (ex. 3541976724)
// utifrån php-funktionerna nedan;
// mt_srand((double)microtime()*1000000);
// mt_rand();
}

// utifrån det slumpade "lösenordet" ovan hämtas saltet
$salt = substr(md5($password), 0, 2);

$password = md5($salt . $plain) . ':' . $salt;

return $password;

}


Drew 2008-07-27 23:44

Det är ju åtminstone vänligt av osCommerce att lägga med saltet i databasen. Känns lite meningslöst att salta då.

SimonP 2008-07-27 23:47

Citat:

Originally posted by dimka@Jul 27 2008, 23:30
Jag tycker att osCommerce funktion att kryptera lösenord är bäst!

Citat:


function encrypt_password($plain) {

$password = '';

for ($i=0; $i<10; $i++) {
* $password .= tep_rand();
* // tep_rand() returnerar ett slumpvis tioställigt numeriskt värde (ex. 3541976724)
* // utifrån php-funktionerna nedan;
* // mt_srand((double)microtime()*1000000);
* // mt_rand();
}

// utifrån det slumpade "lösenordet" ovan hämtas saltet
$salt = substr(md5($password), 0, 2);

$password = md5($salt . $plain) . ':' . $salt;

return $password;

}


Det är inte bra att lägga saltet först som dom gör här: md5($salt . $plain) , eftersom en bruteforce attack blir enklare då, saltet skall läggas sist eller på båda sidorna om lösenordet.

Längden på saltet bör ligga på mer än 2 bytes, för att förhindra dom som sitter på regnbågstabeller där man även "inkluderat" salt, men samtidigt är det onödigt ha en större salt än hashalgoritmens egna styrka, i md5:s fall 16 bytes (32 st hex).

Jonas 2008-07-27 23:58

Kod:

function generateHash($plainText, $salt = null)
{
  if ($salt === null)
    $salt = substr(md5(uniqid(rand(), true)), 0, SALT_LENGTH);
  else
    $salt = substr($salt, 0, SALT_LENGTH);

  return $salt . sha1($salt . $plainText);
}

Varför inte något sådant?

gsoc 2008-07-28 00:26

Citat:

Ursprungligen postat av SimonP
Citat:

Ursprungligen postat av dimka
Jag tycker att osCommerce funktion att kryptera lösenord är bäst
Citat:


function encrypt_password(plain) {
password = ;
for (i=0; i10; i++) {
* password .= tep_rand();
* // tep_rand() returnerar ett slumpvis tioställigt numeriskt värde (ex. 3541976724)
* // utifrån php-funktionerna nedan;
* // mt_srand((double)microtime()*1000000);
* // mt_rand();
}
// utifrån det slumpade lösenordet ovan hämtas saltet
salt = substr(md5(password), 0, 2);
password = md5(salt . plain) . : . salt;
return password;

}




Det är inte bra att lägga saltet först som dom gör här: md5(salt . plain) , eftersom en bruteforce attack blir enklare då, saltet skall läggas sist eller på båda sidorna om lösenordet.
Längden på saltet bör ligga på mer än 2 bytes, för att förhindra dom som sitter på regnbågstabeller där man även inkluderat salt, men samtidigt är det onödigt ha en större salt än hashalgoritmens egna styrka, i md5:s fall 16 bytes (32 st hex).


//Remove

SimonP 2008-07-28 10:49

Citat:

Originally posted by Jonas@Jul 27 2008, 23:58
Kod:

function generateHash($plainText, $salt = null)
{
 * *if ($salt === null)
 * * * *$salt = substr(md5(uniqid(rand(), true)), 0, SALT_LENGTH);
 * *else
 * * * *$salt = substr($salt, 0, SALT_LENGTH);

 * *return $salt . sha1($salt . $plainText);
}

Varför inte något sådant?

Denna funktion är inte så bra av två anledningar:

-salt läggs på före lösenordet
-funktionen rand() är dålig, mt_rand() rekommenderas för kryptofunktioner

Jonathan P 2008-07-28 11:37

Citat:

Originally posted by Drew@Jul 27 2008, 23:44
Det är ju åtminstone vänligt av osCommerce att lägga med saltet i databasen. Känns lite meningslöst att salta då.
Man måste ju veta saltet för att kunna jämföra lösenordet i databasen med det som användaren uppger vid en autentisering. Fördelen med att ha ett dynamiskt salt är att förhindra möjligheten att kunna bruteforcea en hel databas med en regnbågstabell.

jimmie 2008-07-28 12:58

Citat:

Ursprungligen postat av SimonP
Citat:

Ursprungligen postat av Jonas
Kod:

function generateHash($plainText, $salt = null)
{
 * *if ($salt === null)
 * * * *$salt = substr(md5(uniqid(rand(), true)), 0, SALT_LENGTH);
 * *else
 * * * *$salt = substr($salt, 0, SALT_LENGTH);

 * *return $salt . sha1($salt . $plainText);
}

Varför inte något sådant?

Denna funktion är inte så bra av två anledningar:

-salt läggs på före lösenordet
-funktionen rand() är dålig, mt_rand() rekommenderas för kryptofunktioner

Nu har jag saltet längst bak men har funderat lite på varför man egentligen gör det? På vilket sätt blir bruteforce svårare?

Att bruteforca antingen xxxxxxxxxxf3931e5339f5073b23188d1b357715a0 eller f3931e5339f5073b23188d1b357715a0xxxxxxxxxx bör väl kräva samma antal försök?

Obs. är måndag idag så hjärnan är inte riktigt igång än :)

tartareandesire 2008-07-28 14:02

I den här artikeln från Php Security Consortium läggs också saltet i början av strängen [antar att Jonas exempel ovan är hämtat därifrån]. Tycker inte heller det borde göra någon skillnad?

SimonP 2008-07-28 16:05

Det är lite svårt att förklara, egentligen måste man kolla på algoritm-koden för att förstå det helt...

Men t.ex MD5 använder 6 st integers för att spara den interna statusen/contexten inuti algoritmen, varje gång man hashar någonting så är det dessa som ändrar värde, förenklat sagt.

Så om jag hashar saltet "4398jdfshjreg85r9t985dsflkjdsfijl98" kommer att integer:na att se ut ungefär så här efter att md5-algoritmens kärna, md5_update, körts igenom:
state[0] = 0x12452301;
state[1] = 0xbfcddb89;
state[2] = 0x18ba0cfe;
state[3] = 0x78325476;
count1=22
count2=3

Sen lägger jag på lösenordet "mittlösenord", efter att md5_update är klar ändras variablerna då till:

state[0] = 0x18442341;
state[1] = 0xebc4db81;
state[2] = 0x634ba0fb;
state[3] = 0x4ee25498;
count1=11
count2=7

Om inget mer skall hashas kör man den sista funktionen (md5_final) för att för fram den slutgiltiga hashsumman.

Internt så består alla hashfunktioner av 3 funktioner, _init(), _update() och _final()
Så för ovanstående exempel blir det alltså nedanstående för att leta efter lösenordet:
Kod:

MD5_CONTEXT ctx;

bruteforce loop
{
        ctx = md5_init(NULL);
        md5_update(ctx,"4398jdfshjreg85r9t985dsflkjdsfijl98");
        md5_update(ctx,brutestring);
        summa = md5_final(ctx);
        if (summa == myhash) exit;
}

Om jag nu vill snabba upp en bruteforce-attack sparar jag undan värdena i ctx efter hashningen av saltet:

Kod:

MD5_CONTEXT ctx;
MD5_CONTEXT backupctx;

ctx = md5_init(NULL);

// Hasha saltet
md5_update(ctx,"4398jdfshjreg85r9t985dsflkjdsfijl98");

// Spara undan den interna statusen
backupctx = ctx;

bruteforce loop
{
        ctx = md5_init(backupctx);
        md5_update(ctx,brutestring);
        summa= md5_final(ctx);
        if (summa == myhash) exit;
}

-----------Ovanstånde är bara Pseudocode-------

Jag slipper nu att köra md5_update två gånger, vilket innebär att jag sparar CPU-tid.

Om man lägger saltet sist är är det går det ej att spara undan den interna statusen på samma sätt eftersom "brutestring" ändras hela tiden.

jimmie 2008-07-28 16:28

Citat:

Originally posted by SimonP@Jul 28 2008, 15:05
Det är lite svårt att förklara, egentligen måste man kolla på algoritm-koden för att förstå det helt...

Men t.ex MD5 använder 6 st integers för att spara den interna statusen/contexten inuti algoritmen, varje gång man hashar någonting så är det dessa som ändrar värde, förenklat sagt.

Så om jag hashar saltet "4398jdfshjreg85r9t985dsflkjdsfijl98" kommer att integer:na att se ut ungefär så här efter att md5-algoritmens kärna, md5_update, körts igenom:
state[0] = 0x12452301;
state[1] = 0xbfcddb89;
state[2] = 0x18ba0cfe;
state[3] = 0x78325476;
count1=22
count2=3

Sen lägger jag på lösenordet "mittlösenord", efter att md5_update är klar ändras variablerna då till:

state[0] = 0x18442341;
state[1] = 0xebc4db81;
state[2] = 0x634ba0fb;
state[3] = 0x4ee25498;
count1=11
count2=7

Om inget mer skall hashas kör man den sista funktionen (md5_final) för att för fram den slutgiltiga hashsumman.

Internt så består alla hashfunktioner av 3 funktioner, _init(), _update() och _final()
Så för ovanstående exempel blir det alltså nedanstående för att leta efter lösenordet:
Kod:

MD5_CONTEXT ctx;

bruteforce loop
{
        ctx = md5_init(NULL);
        md5_update(ctx,"4398jdfshjreg85r9t985dsflkjdsfijl98");
        md5_update(ctx,brutestring);
        summa = md5_final(ctx);
        if (summa == myhash) exit;
}

Om jag nu vill snabba upp en bruteforce-attack sparar jag undan värdena i ctx efter hashningen av saltet:

Kod:

MD5_CONTEXT ctx;
MD5_CONTEXT backupctx;

ctx = md5_init(NULL);

// Hasha saltet
md5_update(ctx,"4398jdfshjreg85r9t985dsflkjdsfijl98");

// Spara undan den interna statusen
backupctx = ctx;

bruteforce loop
{
        ctx = md5_init(backupctx);
        md5_update(ctx,brutestring);
        summa= md5_final(ctx);
        if (summa == myhash) exit;
}

-----------Ovanstånde är bara Pseudocode-------

Jag slipper nu att köra md5_update två gånger, vilket innebär att jag sparar CPU-tid.

Om man lägger saltet sist är är det går det ej att spara undan den interna statusen på samma sätt eftersom "brutestring" ändras hela tiden.

Härligt bra svar!

MMC 2008-07-28 17:36

Otroligt roligt att se kompetens av den här klassen på en forumdel som oftast består av frågor om hur man ändrar saxad PHP-kod till att skriva ut A istället för B. Tack, SimonP!

emilv 2008-07-28 18:10

Citat:

Originally posted by Drew@Jul 27 2008, 23:44
Det är ju åtminstone vänligt av osCommerce att lägga med saltet i databasen. Känns lite meningslöst att salta då.

Det är inte alls meningslöst. Med ett dynamiskt salt (unikt för varje användare) måste lösenordet knäckas för varje användare. Med ett enda fast salt kan man räkna ut ett lösenord och sedan jämföra mot samtliga användare för se om det träffar någon, eller helt sonika räkna ut regnbågstabeller för det aktuella saltet.
Exempel:

Användare 1 - Lösen: apa
Användare 2 - Lösen: banan

== Fast salt ==
Säg att vi (attackeraren) hashar lösenordet banan tillsammans med det fasta saltet. Då kan vi testa denna hash mot hasharna för båda användarna och se, vi får en träff med en enda uträkning.

== Dynamiskt salt ==
Nu hashar attackeraren ordet banan för varje enskild användare, vilket ökar tidsförbrukningen avsevärt om det är många användare.


Man kan ju dessutom ha både ett fast (i sin applikationskod) och ett dynamiskt (i databasen) salt, för att göra det svårare om man bara får reda på det ena saltet. Man kan om man vill försöka lagra saltet i en egen tabell, eller med applikationskod räkna ut saltet från exempelvis användarnamn och registreringsdatum, men det är inte säkert att det är värt besväret.

Yepp 2008-07-28 22:02

Citat:

Originally posted by MMC@Jul 28 2008, 16:36
Otroligt roligt att se kompetens av den här klassen på en forumdel som oftast består av frågor om hur man ändrar saxad PHP-kod till att skriva ut A istället för B. Tack, SimonP

Instämmer till fullo! Härligt när man känner att man verkligen kan lära sig mer, och samtidigt får inse hur lite man själv faktiskt kan. Precis den här typen av resurser som efterlängtas. Kjempegreit helt enkelt!

Jonas 2008-07-29 00:08

Citat:

Originally posted by tartareandesire@Jul 28 2008, 14:02
I http://phpsec.org/articles/2005/password-hashing.html från Php Security Consortium läggs också saltet i början av strängen [antar att Jonas exempel ovan är hämtat därifrån]. Tycker inte heller det borde göra någon skillnad?


Det är samma kod. Tyckte det var ett bra exempel. Synd bara att man nu har verkställt det hela när man får läsa vad SimonP skrivit.

Underbart skrivit SimonP, creds till dig.

SimonP 2008-08-01 13:12

Citat:

Originally posted by Jonas@Jul 29 2008, 00:08
Det är samma kod. Tyckte det var ett bra exempel. Synd bara att man nu har verkställt det hela när man får läsa vad SimonP skrivit.

Underbart skrivit SimonP, creds till dig.

Tack för era vänliga ord!
Det är som sagt ett mkt komplext ämne, det är ofta man ser sk. "experter" som postar felaktig eller dålig kod på nätet, ur säkerhetsmässig synpunkt.

Jonas, det är dock ingen större katastrof , om någon lyckas dumpa databaser där man lagt saltet först kan attackerarna iofs tjäna ca 20-30% tidsmässigt vid bruteforce-attacker, men det finns ju flera andra fördelar med salt, som inte påverkas av att lägger det först eller sist, t.ex attacker som sker med regnbågstabeller blir oftast värdelösa, eller att två olika användare som använder samma lösenord får olika hashsummor tack vara saltet, etc.

Funktionen rand() bör man generellt sett undvika, inte ens om man sysslar med spel bör man använda rand(), dels fungerar den bättre eller sämre beroende på vilken OS servern kör, sen är den inte threadsafe heller, och på vissa operativsystem kan man förutse vilka nummer som slumpas fram, och då försvinner ofta hela meningen med en PRNG (slumptalsgenerator).

Från Linux manualen:
Citat:


The function rand() is not reentrant or thread-safe, since it uses hidden state that is modified on each call. This might just be the seed value to be used by the next call, or it might be something more elaborate. In order to get reproducible behaviour in a threaded application, this state must be made explicit. The function rand_r() is supplied with a pointer to an unsigned int, to be used as state. This is a very small amount of state, so this function will be a weak pseudo-random generator

Om man vill ha hyffsat bra slumptal till t.ex lösenordssalt, spel eller annat är det bättre att byta ut rand() mot mt_rand().

Ska man använda slumptal till nycklar för stark kryptering räcker inte ens mt_rand() till. Teorin bakom CSPRNG:s (kryptografisk säkra slumptalsgeneratorer) är mer komplicerad än för vanliga PRNG:s.

Vissa webbaserade tjänster, t.ex pokersidor kör faktiskt med TRNG:s (äkta slumptalsgeneratorer) inpluggade i servern via USB, just för att få så "korrekta" slumpnummer som det är möjligt.

Marcin 2008-08-11 06:56

MD5 ses väl som gränsande till förlegat.

Varför in en SHA512-hash på lösenord med ett långt salt, unikt för varje användare. Må verka som overkill men förhoppningsvis behöver man inte oroa sig ett tag framöver.


Här finns lite performance-tabeller: http://msdn.microsoft.com/en-us/library/ms978415.aspx

SimonP 2008-08-11 10:19

Citat:

Originally posted by Marcin@Aug 11 2008, 06:56
MD5 ses väl som gränsande till förlegat.

Varför in en SHA512-hash på lösenord med ett långt salt, unikt för varje användare. Må verka som overkill men förhoppningsvis behöver man inte oroa sig ett tag framöver.


Här finns lite performance-tabeller: http://msdn.microsoft.com/en-us/library/ms978415.aspx

Fast som lösenordshash funkar MD5 fortfarande bra, SHA-xxx är bättre främst för att en bruteforce-attack tar lite längre tid.

SHA-512 faktiskt helt overkill, och även onödigt. Dels så drar den betydligt mer CPU och dels så ökar lagringsutrymmet för hasharna med 100%. Jag skulle vilja jämföra det med att nån försöker bygga ett bombsäkert hus där man har 30 cm tjocka betongväggar och har satt in en 40cm tjock ståldörr (SHA-256) , huset blir inte säkrare för att man byter ut dörren mot en 80 cm tjock ståldörr (SHA-512), det är ändå väggarna som är den svaga länken...

Så länge ingen hittar en svaghet i SHA-256 kommer den räcka ända tills man har kvantdatorer som fungerar i praktiken (för kryptografi), och det är långt, långt dit :ph34r:

znap 2008-08-11 22:28

Tar tillfället i akt och frågar om denna funktion är en bra lösning. Själv känner jag mig hyffsat noob på det här med säker kryptering av lösenord. Med följande funktion följer jag dessa principer som jag snappat upp på lite här och där på nätet.

- Blanda md5 och sha1
- Kryptera flera gånger om
- Använd ett dynamiskt salt kopplat till användarens lösenord
- Använd även ett statiskt salt som man "gömmer" någonstans i applikationskoden

Kod:

        function generatePassword($password, $salt) {
 $str = md5($password.$salt);
 for($i=0; $i<5; $i++) {
        $str = sha1($str);
 }       
 return md5($salt.($str).$salt.STATIC_SALT);       
        }

Är något onödigt? Är det något annat jag bör tänka på?

// Vic

SimonP 2008-08-11 22:57

Citat:

Originally posted by znap@Aug 11 2008, 22:28
- Använd ett dynamiskt salt kopplat till användarens lösenord
- Använd även ett statiskt salt som man "gömmer" någonstans i applikationskoden


Bara man inte använder inte ett salt som utvinns från användarens lösenord, saltet ska helst genereras slumpmässigt.
Att sedan lägga på ett statiskt salt är bra.

Så din funktion ser bra ut, förutsatt att det dynamiska saltet är ok.

znap 2008-08-12 00:12

Ok, tack för ditt svar! Saltet utvinns inte från användarens lösenord, utan varje användare får ett hyffsat unikt salt.

SimonP 2008-09-26 14:31

Citat:

Originally posted by SimonP@Aug 1 2008, 13:12
Funktionen rand() bör man generellt sett undvika...
Tänkte bara visa ett IRL exempel på en ny exploit som utnyttjar den dåliga rand() funktionen i PHP, som jag tidigare skrev om.

http://milw0rm.com/exploits/6392

Den kan vara många svenska SMF-forum som är öppna för denna attack:
http://www.google.com/search?hl=sv&lr=lang...2&start=70&sa=N

För att kontrollera om man påverkas av denna exploit:
Kod:

<?php
echo getrandmax();
?>

Om man får en randmax värde som är lågt, typ < 65536, så bör man fixa detta.

Jonas 2008-09-26 15:22

Citat:

Originally posted by znap@Aug 11 2008, 22:28

Kod:

function generatePassword($password, $salt) {
 $str = md5($password.$salt);
 for($i=0; $i<5; $i++) {
 $str = sha1($str);
 }
 return md5($salt.($str).$salt.STATIC_SALT);
}


Får man fråga varför du skriver över $str 5ggr ?

Dimme 2008-09-26 19:09

Vad än du gör KAN brutoforcas om hackaren känner till din krypteringsalgoritm. Därför säg till att inte sprida här eller någon annanstans koden till din egen algoritm, sen kan du skriva den hur du vill.

eg0master 2008-09-27 11:12

Citat:

Originally posted by Dimme@Sep 26 2008, 19:09
Vad än du gör KAN brutoforcas om hackaren känner till din krypteringsalgoritm. Därför säg till att inte sprida här eller någon annanstans koden till din egen algoritm, sen kan du skriva den hur du vill.
Det där är ett felaktigt uttalande som dessutom uppmanar till dåliga lösningar ur säkerhetssynvinkel.
Jag kanske märker ord, men allt kan bruteforcas oavsett algoritm givet att man har tillräckligt med tid. Kännedom om algoritmen (om den är dålig) gör dock att man kan ta genvägar i attacken så att man inte behöver göra en brute force utan kan koncentrera sig på en mindre mängd möjliga nycklar/lösenord.

En av de första saker man får lära sig om kryptering och olika algoritmers säkerhet är att man skall alltid utgå ifrån att motståndaren känner till algoritmen, men inte nyckeln när man bedömer styrkan hos ett krypto. En krypteringsalgoritm som bygger på att en del av algoritmen är hemlig är värdelös eftersom algoritmen inte går att byta ut. Det är bara en tidsfråga innan algoritmen kommer i fiendens händer. Därför är det att uppmana till dåliga lösningar att påstå att man skall hålla sin algoritm hemlig för det invaggar dig i en falsk säkerhet om din algoritms styrka.

Däremot måste vi anta (när vi värderar styrkan av algoritmen) att nyckeln (i det här fallet saltet) är okänd. Och då är ju ett unikt salt per användare, som är lagrat i databasen sannolikt den bästa lösningen.Och vi måste utgå ifrån att den somanvänder en sådan algoritm vet hur han skyddar sin databas så att inte salten hamnar i felaktiga händer. Men det handlar om säker lagring av nycklar och har inget med algoritmen att göra.

emilv 2008-09-27 22:34

Citat:

Originally posted by eg0master@Sep 27 2008, 11:12
Däremot måste vi anta (när vi värderar styrkan av algoritmen) att nyckeln (i det här fallet saltet) är okänd. Och då är ju ett unikt salt per användare, som är lagrat i databasen sannolikt den bästa lösningen.
Om vi skapar en algoritm som är helt bombsäker så länge nyckeln är hemlig men värdelös om man känner till nyckeln, då? Vad är då meningen med att kryptera lösenorden från första början, när både lösenorden och kryptonyckeln lagras sida vid sida?

Jag föredrar en hash med dubbla salt, ett som lagras i applikationskoden och ett dynamiskt som lagras med användaren i databasen. På så sätt måste man få reda på båda för att knäcka lösenordet. Det finns åtskilliga exempel på när knäckare fått tag på databasen med hjälp av en SQL-injektion, men inte fått tag på applikationskoden. En lösning som kräver både applikationskod och databas för att knäcka (utan råkraftsattack) är därför säkrare än en som bara kräver databasen.

eg0master 2008-09-28 11:45

Att spara ett krypterat lösenord tillsammans med nyckeln är som at ha det i klartext - ja. Men nu pratar vi ju om envägskryptering (dvs en hash). Vi vet idag at md5 inte är så säkert eftersom det går att återskapa en hash utan att känna till lösenordet. Krypterar du istället lösenordet med SHA-512 så är du iaf vad vi vet idag säker.

En annan viktig anledning till att kryptera lösenordet är att bara användaren skall känna till lösenordet. Det bästa är ju alltid om lösenordet krypteras på klienten hos användaren så att den som "äger sidan" aldrig ser användarens lösenord. Det ärju bara at acceptera att de flesta använder samma lösenord på många olika sajter och om krypteringen sker redan på klienten så får individen ett litet extra skydd.

Bara för att du har ett salt som ligger i applikationskoden betyder det inte att du har en hemlig algoritm. Det finns inget likhetstecken mellan algoritm och applikationskod (lika lite som det som ligger i databasen alltid ärnyckeln). Det du beskriver är en tvådelad nyckel där de två delarna är lagrade på två olika ställen. Självklart är det säkrare att använda en metod där nyckeln är tudelad på detta sätt eftersom gemene man verkar ha så svårt att säkra upp sina databaser.

Så eftersom sha512 väl saknas i php och folk misslyckas med att säkra sina databaser om och om igen så är väl den bästa lösningen att använda sha1 och inte md5. sha1 är bätre än md5. Ha gärna ett javascript som hashar lösenordet en gång med SALT1 på klienten innan det skickas (ger användaren en extra trygghet att sajtägaren inte kan sniffa lösenordet). Hasha en gång till med SALT2 som finns i databasen (ett per användare). Hasha ytterligare en gång med ett salt som finns i applikationskoden. Det är väl det bästa man kan göra under omständigheterna.

Avslutningsvis en liten jämförelse mellan två olika algoritmer och nycklar:
Algoritm 1: Skapa en ny sträng med två tecken, följt av lösenordet, följt av två tecken. Kör SHA1 på det.
Algoritm 2: Skapa en ny sträng av användarnamnet och lösenordet. Kör SHA1 flera gånger på det.

Om vi gissar att attackeraren har tillgång till allt utom nyckeln, dvs till och med har en hash som är skapad utifrån ett känt lösenord så är styrkan följande:
Algoritm 1 har då en "nyckel" på fyra tecken. Om vi dessutom vet att det är stora bokstäver (A-Z) har vi totalt 456976 olika kombinationer som måste prövas.
Algoritm 2 har bara "antalet gånger SHA1 körs" som nyckel. och det är ju troligen ett ganska litet tal.

Avslutningsvis 2:
En sista sak att komma ihåg är att inget krypto är säkert. Det enda styrkan på ett krypto säger är hur lång tid det tar att knäcka det givet en viss mängd resurser. men grundtesen är alltid: Algoritmen känd - nyckeln okänd.

stakes 2008-09-28 12:55

Citat:

Originally posted by eg0master@Sep 28 2008, 11:45
Så eftersom sha512 väl saknas i php och folk misslyckas med att säkra sina databaser om och om igen så är väl den bästa lösningen att använda sha1 och inte md5. sha1 är bätre än md5. Ha gärna ett javascript som hashar lösenordet en gång med SALT1 på klienten innan det skickas (ger användaren en extra trygghet att sajtägaren inte kan sniffa lösenordet). Hasha en gång till med SALT2 som finns i databasen (ett per användare). Hasha ytterligare en gång med ett salt som finns i applikationskoden. Det är väl det bästa man kan göra under omständigheterna.
Det finns sha256 i php i funktionen mhash() (som jag brukar använda mig av) sen finns det även ett PECL extension som ger dig tillgång till SHA384 samt SHA512 (bör för övrigt vara installerad by default om du har PHP 5.1.2 eller nyare)

http://se.php.net/manual/en/function.hash-algos.php

EDIT as of PHP 5.3.0 så används inte mhash() längre utan bara hash() som då även ger dig tillgång till sha512.

stakes 2008-09-28 13:10

Problemet ligger dock kvar i att det inte finns något sätt att sha512 lösenord i javascript (rätta mig om jag har fel), vilket gör att det skickas i klartext innan det når servern, om du inte har en SSL anslutning dvs. Av den anledningen ligger jag kvar med sha256 i mina applikationer.

Jonas 2008-09-28 13:14

Citat:

Originally posted by stakes@Sep 28 2008, 13:10
Problemet ligger dock kvar i att det inte finns något sätt att sha512 lösenord i javascript (rätta mig om jag har fel), vilket gör att det skickas i klartext innan det når servern, om du inte har en SSL anslutning dvs.



SSL är det enda rätta oavsett...

Om du kodar på clientside, ja? Vad händer? Jo, du skickar en hash istället för ett lösenord, i vilket fall som helst så är hashen lösenordet istället.
Sniffar man trafiken så behöver man bara skicka hashen istället.

stakes 2008-09-28 13:39

Edit: läste igenom vad du skrev igen och ser att jag misstolkade helt.. :)

Ja som sagt.. SSL är det ända rätta om man vill vara på det torra.

Den ända tryggheten att hasha lösenordet med javascript sha256 är ju att hackaren inte får reda på själva lösenordet som potentiellt kanske används av användaren till andra konton på andra sidor (typ mailkonto etc.). SÅ jag syftade inte på att det var någon ersättare till SSL.

SimonP 2008-09-28 13:48

Citat:

Originally posted by Jonas@Sep 28 2008, 13:14
Om du kodar på clientside, ja? Vad händer? Jo, du skickar en hash istället för ett lösenord, i vilket fall som helst så är hashen lösenordet istället.
Sniffar man trafiken så behöver man bara skicka hashen istället.

Fast det är mkt bättre för användarna om attackeraren bara får tag på hashen istf. lösenordet, det är ju ofta som attackerarna försöker använda lösenordet på andra webbplatser.

Det bästa är att köra krypteringen på klientsidan och skydda trafiken med SSL.

stakes 2008-09-28 13:52

Citat:

Ursprungligen postat av SimonP
Citat:

Ursprungligen postat av Jonas
Om du kodar på clientside, ja? Vad händer? Jo, du skickar en hash istället för ett lösenord, i vilket fall som helst så är hashen lösenordet istället.
Sniffar man trafiken så behöver man bara skicka hashen istället.

Fast det är mkt bättre för användarna om attackeraren bara får tag på hashen istf. lösenordet, det är ju ofta som attackerarna försöker använda lösenordet på andra webbplatser.

Det bästa är att köra krypteringen på klientsidan och skydda trafiken med SSL.

Att hasha lösenordet på klientsidan och skicka det med en SSL anslutning blir väl kaka på kaka? Eller har jag missat något :)

SimonP 2008-09-28 13:56

Citat:

Originally posted by stakes@Sep 28 2008, 13:52
Att hasha lösenordet på klientsidan och skicka det med en SSL anslutning blir väl kaka på kaka? Eller har jag missat något :)
Ja, SSL skyddar bara trafiken, SSL har inget med webbsidans egna script att göra.

stakes 2008-09-28 14:12

Citat:

Ursprungligen postat av SimonP
Citat:

Ursprungligen postat av stakes
Att hasha lösenordet på klientsidan och skicka det med en SSL anslutning blir väl kaka på kaka? Eller har jag missat något :)

Ja, SSL skyddar bara trafiken, SSL har inget med webbsidans egna script att göra.

Jo det är jag medveten om, men frågan lyder då, varför hasha ett lösenord som skall skickas under en skyddad anslutning? Bortsett från att förhindra att ägaren av sajten hijackar lösenordet då...

SimonP 2008-09-28 22:07

Citat:

Originally posted by stakes@Sep 28 2008, 14:12
Jo det är jag medveten om, men frågan lyder då, varför hasha ett lösenord som skall skickas under en skyddad anslutning? Bortsett från att förhindra att ägaren av sajten hijackar lösenordet då...
Det , det kan finnas flera anledningar där SSL inte hjälper helt:
1. Ägaren är en bad guy
2. Man sitter på en delad webbserver där en annan webbsida blivit hackad och på så sätt kommer dom åt din webbsida
3. Servern blir stulen/omdirigerad

För ovanstående fall kan man göra en del grejor för att försvåra processen för hackarna:

-Skydda serverkoden, t.ex en med en PHP-encryptor
-Skydda klientkrypteringen med en signering, vilket innebär att om hackaren skickar ut en falsk klientkryptering så får klienten upp en varningsruta i webbläsaren, eller se till att klientkrypteringen måste installeras som en plugin i webbläsaren istf. att den skickas från servern.

Den bästa anledningen till att aldrig lagra lösenord i klartext är väl att hackarna måste vänta till varje användare loggar in för att kunna plocka lösenordet/hashen (dvs. man använder salt+en bra hashrutin i databasen)

Man kan göra all kryptering med Javascript, SHA-512, PGP etc. , nackdelen är att det går långsammare + att det är mkt svårare att göra någon sorts signering av klientkoden, Java/ActiveX är bättre på detta.

stakes 2008-09-28 23:50

Citat:

Ursprungligen postat av SimonP
Citat:

Ursprungligen postat av stakes
Jo det är jag medveten om, men frågan lyder då, varför hasha ett lösenord som skall skickas under en skyddad anslutning? Bortsett från att förhindra att ägaren av sajten hijackar lösenordet då...

Det , det kan finnas flera anledningar där SSL inte hjälper helt:
1. Ägaren är en bad guy
2. Man sitter på en delad webbserver där en annan webbsida blivit hackad och på så sätt kommer dom åt din webbsida
3. Servern blir stulen/omdirigerad

För ovanstående fall kan man göra en del grejor för att försvåra processen för hackarna:

-Skydda serverkoden, t.ex en med en PHP-encryptor
-Skydda klientkrypteringen med en signering, vilket innebär att om hackaren skickar ut en falsk klientkryptering så får klienten upp en varningsruta i webbläsaren, eller se till att klientkrypteringen måste installeras som en plugin i webbläsaren istf. att den skickas från servern.

Den bästa anledningen till att aldrig lagra lösenord i klartext är väl att hackarna måste vänta till varje användare loggar in för att kunna plocka lösenordet/hashen (dvs. man använder salt+en bra hashrutin i databasen)

Man kan göra all kryptering med Javascript, SHA-512, PGP etc. , nackdelen är att det går långsammare + att det är mkt svårare att göra någon sorts signering av klientkoden, Java/ActiveX är bättre på detta.

Låter vettigt, tack för tipsen.

stakes 2008-09-29 09:44

Btw vart hittar jag SHA-512 för javascript? Har googlat men utan framgång.

SimonP 2008-09-29 10:08

Ex: http:// jssha .sourceforge.net/

Men som jag skrev tidigare i denna tråd är SHA-512 overkill.


Alla tider är GMT +2. Klockan är nu 13:43.

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