Panelen



Forumnavigering
Senast inloggade
RSS
Sponsorer
Artiklar > Säkerhet

Lösenordshantering - MD5 och salt

När man pratar om lösenord så brukar man säga att det är användarens skylldighet att välja ett långt och säkert lösenord, och det är helt sant, till viss del. Men du som utvecklare har också ett stort ansvar i det hela, du måste se till att lösenorden sparas i databasen på ett säkert sätt. Om någon utomstående skulle lyckas ta sig in i din databas så vore det rena rama julafton för honom/henne om alla lösenord är sparade i klartext. Det är väldigt viktigt att du på något sätt krypterar sparade lösenord, och i den här artikeln har jag tänkt att gå igenom ett effektivt sätt.

Att tänka på: Även om din sida inte är så populär och det inte gör så mycket om databasen blir stulen så kan dina medlemmar ha samma lösenord på andra sidor, som är betydligt viktigare. Ge dina besökare den säkerhet de förtjänar.

Kryptering har funnits i urminnes tider och innebär att man döljer ett meddelande för obehöriga läsare, och det är ju precis så vi vill ha det med våra lösenord, eller hur? Hur ska vi då bära oss åt för att få ett så optimalt skydd som möjligt? Jo, det finns många olika krypteringsmetoder, men de flesta går på något sätt att dekryptera. Men det finns också så kallade envägskrypteringar som bara går att kryptera och inte dekryptera, det är en sådan kryptering vi ska använda oss av. Funktionen heter md5() och finns inbygd i PHP. Ni som har läst mina tidigare artiklar vet att jag brukar visa exempel i just PHP och inte ASP, så blir det även denna gång.

MD5 är, som sagt, en envägskryptering, eller hash-funktion som det egentligen heter. För att beskriva en hash-funktion på ett enkelt sätt så kan du tänka dig att vi ska kryptera sifferkoden 12345. Vi adderar ihop alla tal i koden: 1 + 2 + 3 + 4 + 5 = 15. Nu har vi fått "hash-summan" 15 genom lite enkel matematik. Men det är inte lika enkelt att gå åt andra hållet. Vi kan inte utgå från summan 15 och lista ut vilka tal vi adderade för att komma fram till 15.

Okej, då sätter vi igång med det praktiska. Vi tänker oss en registeringssida där besökarna ska välja ett lösenord. Du hämtar lösenordet som vanligt och sparar det i en variabel. Men innan du sparar lösenordet i databasen måste du köra den genom MD5-funktionen.


$password = $_POST['password'];

$md5_password = md5($password);



// Sparar $md5_password i databasen

Nu kommer det hashade lösenordet sparas i databasen. Inte så svårt, eller hur? Bra! Men hur ska vi nu bära oss åt när vi ska kontrollera om det är rätt lösenord vid inloggningen? Ta det lungt, det är inte svårt alls. Vi gör bara samma sak igen. Vi hämtar lösenordet som användaren skriver in, kör det genom MD5-funktionen och kollar sedan om det är detsamma som det sparade hash-värdet i databasen.

Vid registering: Hämta inskrivet lösenord -> Kör det genom MD5-funktionen -> Spara i databasen
Vid kontroll: Hämta inskrivet lösenord -> Kör det genom MD5-funktionen -> Jämför med det sparade lösenordet

Nu är lösenorden bra mycket säkrare, men de går faktiskt fortfarande att käcka. Men vadå? Jag sa ju att det inte gick att dekryptera hashade lösenord. Det är helt sant, det går inte. Men det finns personer som har samlat på sig stora listor med hashade ord. Dessa listor innehåller miljontals ord och teckenföljder. Med hjälp av dessa ordlistor kan hackare jämföra dina lösenordshashar med hasharna i ordlistan, och på så sätt hitta rätt lösenord.

För att skydda lösenordet yttligare måste vi därför använda oss av något som kallas salt. Att "salta" ett lösenord innebär att man lägger till några slumpade tecken före eller/och efter lösenordet innan man kör det genom MD5-funktionen. På så sätt är det nästintill omöjligt för hackarna att hitta lösenordshashen i en ordlista. Här är en metod för att salta ett lösenord:


$password = $_POST['password'];

$salt1 = "18gI%f5A";

$salt2 = "@Y4p91bN";

$salt_password = md5($salt1.$password.$salt2);



// Sparar $salt_password i databasen

Om en användare nu skulle valt att använda, till exempel, "internet" som lösenord, som vanligen skulle finnas med i en ordlista, skulle "ordet" 18gI%f5Ainternet@Y4p91bN köras genom MD5 funktionen istället och sparas i databasen. Självklart måste man lägga till salt-nycklarna när man ska kontrollera lösenorden vid inloggning också. 

Det var allt för mig, hoppas du har lärt dig någonting. Kom ihåg att ALDRIG, ALDRIG, ALDIG spara ett lösenord i klartext. Använd MISNST vanlig MD5 och hellst så saltar du lösenorden också. Jag avslutar med att visa några hash-summor, det kan vara bra att veta hur de ser ut.

Internet = c3581516868fb3b71746931cac66390e
frisko = a10c582d03911c2b290ac4fc20b2b594
ASPkoll = 0d5cd30069dea57343dd16da7641136d

Några snabba tips:

  • Använd långa salt
  • Ha unika salt för varje medlem

Andra kryptering-/hashmetoder:

Tack till:

  • Andy_
  • ice

Skapades: 2008-01-21 11:36:49
Skribent: frisko
Lästs 1996 gånger
Betyg: 0 (artikeln har endast 1 röster, det krävs minst 5 för ett betyg)

Kommentarer

john94 sa den 21 januari 2008 kl 13:50:
Mycket bra artikel
Index sa den 21 januari 2008 kl 14:23:
Den här läste jag igårkväll och den här var lika bra som då.
frisko sa den 21 januari 2008 kl 15:57:
Man tackar.
Andy_ sa den 21 januari 2008 kl 16:16:
Tänk att ha salt + systemsalt + lösenord. För har man knäckt systemsalten kan man lätt hitta de andra lösenorden genom att köra rainbow eller liknande. Alltså ska det finnas en salt för varje person med. Ha gärna längre salt med. Sen rekommenderar jag sha512 framför md5.
frisko sa den 21 januari 2008 kl 18:18:
Redigerande artikeln lite. La till två stycken snabba tips, kom gärna med fler. Alltid kul med en så informationsrik artikel som möjligt.
chrillemeter sa den 21 januari 2008 kl 19:35:
Mycket bra artikel. Har alltid undrat vad det innebär att salta ett lösenord.
Själv använder jag SHA1 när jag hashar lösenord.
frisko sa den 21 januari 2008 kl 22:41:
Tack ice.
En liten uppdatering till.
chrillemeter sa den 21 januari 2008 kl 23:01:
Ska faktiskt skriva en artikel om hur man kan göra en Lagrad procedur för säker inloggning i MySQL.
frisko sa den 22 januari 2008 kl 13:18:
Låter bra =]
chrillemeter sa den 25 januari 2008 kl 13:25:
Om man använder mySQL så kan man använda funktionerna
AES_ENCRYPT OCH AES_DECRYPT. Den starkaste krypteringen i MySQL är det.

Funktionerna tar två parametrar. texten som ska krypteras och en hemlignyckel i form av en textsträng.

Lösenordsfältet i databasen måste vara av typen Blob för att kunna använda funktionerna.

Båda parametrarna måste stämma med innehållet i blob-fältet, annars returnerar SQL:en null.

Kombinera detta med MD5 eller SHA1 så får du ett riktigt bra skydd.
Att vid inloggningen måste mata in två olika värden för att logga in ser jag inte som
något problem alls. tar några sekunder mer att göra det.
Mygan sa den 12 november 2008 kl 11:46:
Jag ser en nackdel med denna, om man använder detta i t.ex en community, så är hashen för 2 användare som har samma lösenord likadana. Man kan lägga till användarens namn(nick,smeknamn whatever) på communityn så att hashen blir unik för alla.
© Copyright 2007-2009 Shadi Domat | Version 3.0 | Sidkarta | Policy