2015-07-31

Hur lösenord lagras

(Den följande beskrivningen är en förenkling, en beskrivning av en princip. Experter torde ha åtskilligt att tillägga.)

Då och då kan man läsa om lösenord som kommit på drift. Sajten X har hackats, användarnas lösenord har kommits åt, och därmed har säkerheten helt satts ur spel. I synnerhet om användarna varit slarviga nog att använda samma lösenord på X som på Y och Z.

Hur lagras då lösenorden på sajten? Om jag har angett lösenordet abc på en sajt, vad står i den fil där sajten lagrar inloggningsuppgifter?

Det finns faktiskt sajter som lagrar lösenord i klartext, d.v.s. det står verkligen "användare = Hexmaster, lösenord = abc" någonstans. Sådana amatörer är ett kapitel för sig.

Sajter med en gnutta mer säkerhetstänk lagrar krypterade lösenord. Då skulle det, för att ta ett mycket enkelt exempel, kunna stå "krypterat_lösenord = bcd" i filen med inställningar. Det är inte mycket bättre än att lagra i klartext, så snabbt som dagens datorer kan knäcka även rätt komplicerade krypteringar.

Men det överlägset vanligaste sättet att lagra lösenord på går inte ut på att lagra själva lösenordet. Istället räknar man ut en sorts checksumma för lösenordet. Lite som den sista siffran i personnumret, fast mycket mer avancerat.

Säg att vi har en checksummefunktion, vi kallar den f, som helt enkelt går ut på att summera bokstäverna:

f(abc) > a + b + c > 1 + 2 + 3 = 6

Då skulle det stå "lösenord_checksumma = 6" i den där filen. När någon försöker logga in som mig så räknar datorn ut checksumman för det angivna lösenordet och jämför. Är de lika, så är det OK, och användaren (som förhoppningsvis är jag) loggas in som mig.

Nu är denna checksummefunktionen inte mycket att komma med. Om man vet hur den fungerar (vilket man ska förutsätta; det är dåligt säkerhetstänk att lita till hemliga mekanismer) så är det lätt att ange ett annat lösenord som ger samma checksumma, som "bbb" eller "aaaaaa".

De funktioner som används på riktigt är naturligtvis mycket mer avancerade. En vanlig heter md5; den har sina problem men duger utmärkt som exempel. Denna funktion mixtrar de inblandade siffrorna fram och tillbaka för att skapa en checksumma, eller hash som den kallas, som i fallet "abc" ser ut så här:

md5(abc) = 900150983cd24fb0d6963f7d28e17f72

Med denna metod är det "md5_hashat_lösenord = 90015..." som lagras i filen. När någon försöker logga in som mig räknas hashen ut för det angivna lösenordet och jämförs med den i filen; stämmer de överens, så är det OK.

På samma sätt som med funktionen f så är det helt omöjligt, inte bara i praktiken utan även i teorin, att utifrån hashen gå baklänges och räkna ut lösenordet. Vad man kan göra är att hitta ett lösenord, "abc" eller något annat, som ger rätt resultat. Poängen med ordentliga algoritmer som denna är att det är väldigt mycket svårare att hitta ett sådant än för det enkla exemplet f. Md5 arbetar med 128 bitar vilket ger 340 282 366 920 938 463 463 374 607 431 768 211 456 olika hashar, och i princip finns det inga genvägar; man får gå igenom dem en efter en tills man hittar en som funkar.

Det finns mycket mer att läsa i ämnet, om olika algoritmer, saltning, knäckningsmetoder och annat, men denna princip är densamma: Det man lagrar är inte lösenord, ens i aldrig så krypterad form, utan checksummor/hashar av ett eller annat slag.

2 kommentarer:

Joakim E sa...

Bra sammanfattning! Men ska man vara ordentlig lagrar man inte checksummor av lösenord heller. Nackdelen är att man då direkt kan se vilka användare som använt samma lösenord, och om man (på ett eller annat sätt) kommer över ett av dem vet man direkt vilka konton man kommer åt. I stället lagrar man en checksumma av lösenordet plus lite andra data. Kan vara användarnamnet och/eller någon slumpgenererad eller tidsbaserad sträng till exempel. I det senare fallet måste förstås också extrainfon lagras i databasen.

Hexmaster sa...

Tackar! Ordentlig, i bemärkelsen utförlig, är just vad jag försökte vara tydlig med att jag inte var. :-) Men det blir bra med ytterligare info i kommentarerna.