Permalänk
Medlem

[php] Hasha inloggningsuppgifter

Jag funderar över det här med att hasha lösenorden och använda salt. Jag läste på http://phpsec.org/articles/2005/password-hashing.html om det, men jag förstår inte riktigt hur de menar. Jag vet varför man ska använda salt och hash och så, men menar de att man ska spara saltet i databasen tillsammans med det hashade lösenordet?
Ex.

CREATE TABLE users(username, password, salt)

...och alltså ha ett unikt salt för varje användare? När ska saltet genereras och sparas? Bara vid registrering eller ska det ändras vid varje inloggning?

Permalänk
Medlem

är det inte lite overkill att slumpa fram ett salt för varje användare?

Visa signatur

E6300 | Thermalright Ultra-120 eXtreme + Noctua 120mm 1200rpm | Gigabyte GA-965P-DS3 | 3GB Corsair XMS2-6400 CL5

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av sunkBurk
är det inte lite overkill att slumpa fram ett salt för varje användare?

Jag vet inte, men är det inte det de menar i artikeln? För isåfall måste man ju nästan använda sig av hash-algoritmer som finns inbyggda i mysql för att kontrollera lösenord utan absurda omvägar.

SELECT COUNT(*) FROM users WHERE SHA1(CONCAT(password, salt)) == SHA1($_POST['password'])

Jag vill ju använda sha256, men det finns ju inte inbyggt i mysql.

Permalänk
Medlem
Citat:

Using a salt overcomes the issue of multiple accounts with the same password revealing themselves with identical hashes in your database. Although two passwords may be the same the salts will almost certainly be different, so the hashes will look nothing alike.

Skulle man använda samma salt till alla användare skulle det vara rätt meningslöst. Då skulle dom kunna se att dom har samma lösenord som nån annan iaf.

Visa signatur

flippy @ Quakenet

Permalänk
Medlem

En fördel med att salta sina passwords är ju att minska risken för att dessa skall finnas med i ett rainbowtable. Använder man samma salt på alla användare räcker det med att generera ett rainbowtable för detta salt. medans om man har ett unikt salt för varje användare försvinner helt poängen med att använda rainbowtables.

Det enklaste sättet är nog att använda användarnamnet som salt.

Permalänk
Medlem

Unikt salt för varje användare är klart bäst.
Med ett enda salt så går det som sagt att generera rainbowtables för det saltet, men det är fortfarande mycket säkrare än att bara köra vanlig md5 där det finns tables redan.

Permalänk
Medlem

En ganska säkert sätt att spara lösenorden på är att köra: password = sha1(sha1(CONCAT(sha1(password), CONCAT(salt, id))))
ID är då det unika rad ID som varje användare har.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av nystan
En ganska säkert sätt att spara lösenorden på är att köra: password = sha1(sha1(CONCAT(sha1(password), CONCAT(salt, id))))
ID är då det unika rad ID som varje användare har.

Det där verkar bara onödigt.
sha1(CONCAT(password,salt)) räcker. Det övriga är bara "security by obscurity".

När en hackare har fått ut alla password ur din databas behöver han bara lägga lite extra tid på att "lista ut" din formel. Har han då själv ett lösenord i din databas tar det nog inte lång tid alls. Eller om han samtidigt får tillgång till källkoden för applikationen (om det är en webapp så är det nog inte så ovanligt att man kommer åt båda).

sha1(CONCAT(password,salt)) räcker om salt är unikt för varje användare, se till att det är några tecken långt typ 8 eller så.

Permalänk
Medlem

hehe jag tycker att allt detta verkar alldeles för overkill men jag är ju inte så säker av mig så...

Jag tycker att man skall lägga mer krut på databaslösenordet och skydda sig med mysql_real_escape_string().

Visa signatur

E6300 | Thermalright Ultra-120 eXtreme + Noctua 120mm 1200rpm | Gigabyte GA-965P-DS3 | 3GB Corsair XMS2-6400 CL5

Permalänk
Citat:

Ursprungligen inskrivet av sunkBurk
hehe jag tycker att allt detta verkar alldeles för overkill men jag är ju inte så säker av mig så...

Jag tycker att man skall lägga mer krut på databaslösenordet och skydda sig med mysql_real_escape_string().

Varför är det overkill? Är det så himla kämpigt att ge varje användare ett slumpat salt?

Visa signatur

Ruby (on rails) är fint!

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av bongo-apan
Varför är det overkill? Är det så himla kämpigt att ge varje användare ett slumpat salt?

Nej förlåt men det jag syftade på var teorin om att salta saltet med salt osv.

Visa signatur

E6300 | Thermalright Ultra-120 eXtreme + Noctua 120mm 1200rpm | Gigabyte GA-965P-DS3 | 3GB Corsair XMS2-6400 CL5

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Tjofras
Det där verkar bara onödigt.
sha1(CONCAT(password,salt)) räcker. Det övriga är bara "security by obscurity".

När en hackare har fått ut alla password ur din databas behöver han bara lägga lite extra tid på att "lista ut" din formel. Har han då själv ett lösenord i din databas tar det nog inte lång tid alls. Eller om han samtidigt får tillgång till källkoden för applikationen (om det är en webapp så är det nog inte så ovanligt att man kommer åt båda).

sha1(CONCAT(password,salt)) räcker om salt är unikt för varje användare, se till att det är några tecken långt typ 8 eller så.

Men det måste ju vara svårare att få fram lösenordet ur SHA1(SHA1('lösenord')). Det är ju sha1-hashen ur sha1-hashen ur lösenordet. Måste ju vara mycket mycket svårare.

Men saltet ska alltså genereras och sparas vid registrering? Man kan ju dessutom generera nytt vid varje inloggning, men det är kanske lite overkill

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Fr0hike

Man kan ju dessutom generera nytt vid varje inloggning, men det är kanske lite overkill

Speciellt med tanke på att det inte blir det minsta säkrare av det

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Buffi
Speciellt med tanke på att det inte blir det minsta säkrare av det

Blir det väl? Eller... okej, det blir det ju faktiskt inte. Hehe.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Fr0hike
Men det måste ju vara svårare att få fram lösenordet ur SHA1(SHA1('lösenord')). Det är ju sha1-hashen ur sha1-hashen ur lösenordet. Måste ju vara mycket mycket svårare.

Men saltet ska alltså genereras och sparas vid registrering? Man kan ju dessutom generera nytt vid varje inloggning, men det är kanske lite overkill

Om du ändå måste skapa rainbowtablet så kan du ju lika gärna skapa det med sha1(sha1(password)). Det man kan säga är ju att det säkert finns färdiga rainbowtables för sha1(password) men inte för sha1(sha1(password)). Men lägger du på ett salt så finns det varken för sha1(password+salt) eller sha1(sha1(password+salt)). Så då måste ett nytt rainbowtable genereras och då spelar det ingen roll hur många gånger du kör hashfunktionen. (det kanske tar lite längre tid att generara det)

Att generera ett nytt salt vid varje inloggning ger ju inget. När väl hackaren väl har fått ut alla hashade password spelar det ju ingen roll om saltet bytts 100 gånger innan det.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Tjofras
Om du ändå måste skapa rainbowtablet så kan du ju lika gärna skapa det med sha1(sha1(password)). Det man kan säga är ju att det säkert finns färdiga rainbowtables för sha1(password) men inte för sha1(sha1(password)). Men lägger du på ett salt så finns det varken för sha1(password+salt) eller sha1(sha1(password+salt)). Så då måste ett nytt rainbowtable genereras och då spelar det ingen roll hur många gånger du kör hashfunktionen. (det kanske tar lite längre tid att generara det)

Att generera ett nytt salt vid varje inloggning ger ju inget. När väl hackaren väl har fått ut alla hashade password spelar det ju ingen roll om saltet bytts 100 gånger innan det.

Ah okej, det förstås.

Jag tänkte att om det byts efter att han/hon har fått tag i det. Men det hjälper ju inget det heller kom jag på.

Okej, så man behöver inte hålla saltet hemligt? För om personen kommer över databasinnehållet så kommer han eller hon ju över saltet också. Eller hur?

Permalänk
Medlem

Om du har användarunikt salt så behövs det genereras en rainbowtable per användare vilket ju inte direkt är optimalt
Så nä, saltet behövs inte hållas hemligt.

Permalänk
Medlem

men saltet bör vara hemligt. Om man inte känner till saltet så får man det ju såklart lite lurigare.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av totoo
men saltet bör vara hemligt. Om man inte känner till saltet så får man det ju såklart lite lurigare.

Vart hade du tänkt spara saltet förutom i databasen om du vill ha användarunikt salt då?

Permalänk
Medlem

nja, alltså du kan ju grunda saltet på något i databasen eller göra vad man nu vill - men bara för att saltet må vara en del av användarnamnet, lösenordet eller användarid eller hur man nu vill ha det så är ju det något som bara hanteras i inloggningskoden hos servern. Det är ju knappast att jag sparar en variabel i användarens cookie som heter "salt" där jag skyltar med vilket salt som används. Det där sitter inkapslat i min inloggningsfunktion.

Genom att få tag i min databas så får man ju inte tag i saltet (även om man kanske är en bra bit på väg).

Jag är ju inte så pass tappad bakom en höna att jag har ett fält i medlemstabellen som heter "salt".

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av totoo
nja, alltså du kan ju grunda saltet på något i databasen eller göra vad man nu vill - men bara för att saltet må vara en del av användarnamnet, lösenordet eller användarid eller hur man nu vill ha det så är ju det något som bara hanteras i inloggningskoden hos servern. Det är ju knappast att jag sparar en variabel i användarens cookie som heter "salt" där jag skyltar med vilket salt som används. Det där sitter inkapslat i min inloggningsfunktion.

Genom att få tag i min databas så får man ju inte tag i saltet (även om man kanske är en bra bit på väg).

Jag är ju inte så pass tappad bakom en höna att jag har ett fält i medlemstabellen som heter "salt".

Det är sant. Man kan ju basera det på t ex första och sista bokstaven i användarnamnet, id, registreringsdatum och annat som är konstant. Eller hur?

Permalänk
Medlem

id är helt okej... Även om jag tycker att man gärna kan ta något som är lite svårare att gissa... Som t.ex. första och sista bokstaven i användarnamnet etc som du själv säger.

Dock ska man veta att ett enkelt salt, vilket som helst (även om det är samma för alla användare) ökar säkerheten REJÄLT... alltså, med tusenstals procent jämfört med en ren md5 på lösenordet skulle jag tro. Att sedan göra individuellt salt ökar rejält ett steg till... att göra saltet lite skyddat ökar inte jättemycket - men tar 10 minuter att implementera, så whatever.

Det ska ju gärna vara så att hackern i princip är rykt om han inte har tillgång till BÅDE databas och serverkoden.

Permalänk
Medlem

En sak du ska akta dig för är att basera saltet på lösenordet. Säg att du tar dom 2 första bokstäverna ur lösernordet för att salta lösenordet, om hackaren kommer fram till detta så räcker det med ett rainbowtable för hela databasen. Men tar du något från användarnamnet så blir det genast mycket bättre.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Tjofras
En sak du ska akta dig för är att basera saltet på lösenordet. Säg att du tar dom 2 första bokstäverna ur lösernordet för att salta lösenordet, om hackaren kommer fram till detta så räcker det med ett rainbowtable för hela databasen. Men tar du något från användarnamnet så blir det genast mycket bättre.

Hmm. Fast de flesta användare har ju olika lösenord? Då borde ju nästan alla ha unika salt också?

Man kan ju ta första och ex tredje/sista (beroende på längd) av lösenord, samma av användarnamn och nåt annat som är konstant men unikt för varje användare. Inte sant?

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Fr0hike
Hmm. Fast de flesta användare har ju olika lösenord? Då borde ju nästan alla ha unika salt också?

Man kan ju ta första och ex tredje/sista (beroende på längd) av lösenord, samma av användarnamn och nåt annat som är konstant men unikt för varje användare. Inte sant?

Det bästa är att saltet är helt slumpmässigt och inte bygger överhuvudtaget på något som kan härledas från lösenordet.

En extra säkerhet som kan löna sig är att inte skicka lösenordet i klartext över nätverket/internet, utan använda javascript för att generera login-hashen och skicka endast den hashen. I login-form så skickar man då saltet som hidden, och genererar hashen som t ex sha1(salt+användarnamn+lösenord) med kanske nån timestamp inbakad i hashen också. Fast det händer nog sällan att någon avlyssnar trafiken såhär, och då är nog TLS/SSL ett bättre skydd.

Det händer ju oftare att någon tar sig in på servern och dumpar hela databasen (och ibland även hela källkoden). Det är då man borde använt ett slumpmässigt salt (med kanske minst 8 tecken).

Om saltet endast skulle bygga på första och sista bokstaven av lösenordet skulle det gå väldigt snabbat räkna ut genom att testa 'p' och 'd'. Om antalet användare är stort finns det sannolikt en del med detta (och andra enkla) lösenord. När man knäckt hur saltet genereras kan man bygga en optimerad rainbowtable för detta. Dock blir det ju väldigt svårt om saltet är helt slumpmässigt. Detsamma gäller om någon får tag på källkoden för loginscriptet eller hela servern.

Man får inte underskatta hur många personer som sitter med enorma rainbowtables och knäcker lösenord för skojs skull (såg man ju bl a på flashback när silentwhisper hackades).

Permalänk
Testpilot
Citat:

Ursprungligen inskrivet av Tjofras
En sak du ska akta dig för är att basera saltet på lösenordet. Säg att du tar dom 2 första bokstäverna ur lösernordet för att salta lösenordet, om hackaren kommer fram till detta så räcker det med ett rainbowtable för hela databasen. Men tar du något från användarnamnet så blir det genast mycket bättre.

Och hur lång tid tror du inte det skulle ta? det man vill skydda sig mot är ju från att sina MD5-summor finns med i existerande tabeller.

Visa signatur

Kolla gärna in min RGB-LED-ljusstake i galleriet
[Gigabyte GA-Z97MX-Gaming 5][Intel Core i5 4690K][Corsair XMS3 16GB][Asus GeForce RTX 2060 Super Dual Evo OC]

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Fr0hike
Hmm. Fast de flesta användare har ju olika lösenord? Då borde ju nästan alla ha unika salt också?

Man kan ju ta första och ex tredje/sista (beroende på längd) av lösenord, samma av användarnamn och nåt annat som är konstant men unikt för varje användare. Inte sant?

Jo men använder du bara lösenordet som salt vet du ju om saltet för varje lösenord när du gör rainbowtablet.

Säg att du tar dom två första bokstäverna i lösenordet som salt. Då använder man lösenordet + "två första tecknen i lösenordet" som indata i hasfunktionen när man genererar rainbowtablet. Saltet är då en funktion av lösenordet så om du genererar ett rainbowtable från en ordlista och ett av orden är "kanelbulle" så vet du att saltet som ska användast är "ka".

Men så fort du blandar in något annat, tex delar av användarnamnet så är det inte längre en funktion av lösenordet

Citat:

Ursprungligen inskrivet av huden
Och hur lång tid tror du inte det skulle ta? det man vill skydda sig mot är ju från att sina MD5-summor finns med i existerande tabeller.

Det tar nog en stund. Men om man bara ska skydda sig mot existerande tabeller behöver du inget unikt salt över huvud taget.

Men om man ska välja ett bra salt är det väll bara dumt att välja ett salt som är en funktion av lösenordet då detta bara gör det lättare att komma åt lösenorden.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Tjofras
Jo men använder du bara lösenordet som salt vet du ju om saltet för varje lösenord när du gör rainbowtablet.

Säg att du tar dom två första bokstäverna i lösenordet som salt. Då använder man lösenordet + "två första tecknen i lösenordet" som indata i hasfunktionen när man genererar rainbowtablet. Saltet är då en funktion av lösenordet så om du genererar ett rainbowtable från en ordlista och ett av orden är "kanelbulle" så vet du att saltet som ska användast är "ka".

Men man måste ju veta lösenordet för att veta saltet då, inte sant? Lösenordet vet man ju inte. Du menar om man tar de två första bokstäverna i lösenordshashen?

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Fr0hike
Men man måste ju veta lösenordet för att veta saltet då, inte sant? Lösenordet vet man ju inte. Du menar om man tar de två första bokstäverna i lösenordshashen?

Om du skapar ett rainbowtable så gör du ju det genom att hasha en massa potensiella lösenord (antingen från en ordlista eller helt enkelt genom att lista alla kombinationer). Så om du ska göra ett rainbowtable för 5-teckens lösenord börjar du med "aaaaa" sen "aaaab". Du kör dessa potensiella lösenord genom en MD5 funktion. Efter att du kört alla lösenord genom md5 funktionen sorterar du listan på det hashade resultatet. Du kan nu köra en divide and conqure sökning på detta.

Om du nu skall skapa denna lista och vet att de 2 första tecknen är saltet så kör du helt enkelt "aa"+"aaaaaa" genom MD5 funktionen. Detta kommer då resultera i ett table som du kan använda för att knäcka alla lösenord (av längden 5) i databasen.

Hade du istället valt ett slumpmässigt salt eller ett användarnamnet som salt så behöver du generera ett rainbowtable per salt. Detta gör att det kommer ta betydligt mycket längre tid att knäcka alla dessa lösenord.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Tjofras
Om du skapar ett rainbowtable så gör du ju det genom att hasha en massa potensiella lösenord (antingen från en ordlista eller helt enkelt genom att lista alla kombinationer). Så om du ska göra ett rainbowtable för 5-teckens lösenord börjar du med "aaaaa" sen "aaaab". Du kör dessa potensiella lösenord genom en MD5 funktion. Efter att du kört alla lösenord genom md5 funktionen sorterar du listan på det hashade resultatet. Du kan nu köra en divide and conqure sökning på detta.

Om du nu skall skapa denna lista och vet att de 2 första tecknen är saltet så kör du helt enkelt "aa"+"aaaaaa" genom MD5 funktionen. Detta kommer då resultera i ett table som du kan använda för att knäcka alla lösenord (av längden 5) i databasen.

Hade du istället valt ett slumpmässigt salt eller ett användarnamnet som salt så behöver du generera ett rainbowtable per salt. Detta gör att det kommer ta betydligt mycket längre tid att knäcka alla dessa lösenord.

Jag förstår fortfarande inte. Hur ska man som hackare veta vilka de två första bokstäverna i lösenordet är? Det är ju lösenordet man försöker luska ut..?