Jag fick uppgiften att bygga en lösenordstillgång till ett affärssystem. Vi bestämde oss för att hasha lösenorden och lagra hashen i databasen.
Exempel:
Lösenord i normaltext: "Kalle Anka"
Lösenord i hashkod: "4ec33c4d232199fea31216e94e17ec28"
Här har vi använt en så kallad MD5-algoritm som kan implementeras med system.security.crypography. Eftersom sådana lösenord är svårtsmälta, sa är det ju ingenting som visas för användaren. De lagras enbart i databasen där den sedan jämförs med det som en användare knappar in som lösenord när denne loggar in.När lösenordet skickas från inloggningssidan så räknar en funktion fram hash-koden av det lösenordet som precis blev inknappat och den jämförs med den hashkod som är sparad i databas.
Två saker behöver man tänka på
1. Hashningen händer i code-behind-sidan, dvs vi skickar lösenordet okrypterad till servern.
Man kan kryptera lösenordet redan på klientsidan med JavaScript men det blir nästa steg. I vårt fall så använder vi https och då är ju informationen krypterad ”by default”. Man bör dock tänka på att en del exploits utnyttjar svagheter i browsern och teoretiskt sett kan ett script ligga och plocka okrypterade lösenord som skickas mellan server/klient eller som lagras i kakor/formfält.
2. Lösenordet är inte återställningsbart, om man tappar bort sitt lösenord så kan man inte få tillbaka det. Man måste välja ett nytt. Eftersom vi inte lagrar lösenordet i databasen utan enbart hashen för lösenordet så finns det inga möjligheter att skicka ut mail med kontouppgifter till användaren.
Däremot så kan man skicka ut återställnings-epost till användarens e-post-adress. Det ger användaren en chans att skriva in ett nytt lösenord som sedan hashas och lagras i databasen. Återställnings-epost skickas enbart ut till användarens kända e-post-adress. Har användaren bytt e-postadress så måste man identifiera sig på ett annat sätt, i interna företagssystem där alla känner varandra är det inga problem att hantera, värre är det på stora communityn, förlorar man tillgången till sin e-postadress och tappar lösenordet så är chansen väldigt liten att man får återställa sitt konto utan man blir av med det helt enkelt.
Men det finns ju även fördelar
1. Det fantastiska med det är ju att det inte går att räkna fram lösenordet bakvänt*. Alla som kan komma åt en databas, i rätt syfte eller vid intrång, kan inte längre se lösenordet som är knuten till ett inloggningskonto.
2. Finns säkert fler fördelar, dem kan ni räkna ut själv.
Brutal force då?
*Nu är det ju så att det går att attackera detta med brute force och rainbow-tabeller och färdiga hashlistor/siter. Har en hacker kommit åt en databas med hashade lösenord så kan de jämföra hasharna med redan crackade hashar, de kan låta program gissa olika lösenord (brutal force) tills hashen hittas.
Om den finns med, sa kvarstår det bara att knappa in det lösenordet och så är hackern där han inte borde vara. Problemet med det här är att om du bara har 5 tecken i ditt lösenord, bara bokstäver, inga specialtecken, så tar det bara några sekunder för brutal-force-programmet att generera alla varianter av lösenord som innehåller 5 tecken och skapa hashkoder av dessa och sedan jämföra mot hashen i databasen.
Så vad gör man för att motverka detta då?
Man kan inte begära av användaren att han måste ha ett 25-tecken långt lösenord med specialtecken och siffror m.m. (vilket skulle ta hackarna tusentals år att köra ”brutal force” mot.)
Jo man ”saltar”.
Salta lösenorden
Man har en lång sträng (som är hemlig) som man lägger till på lösenordet innan man krypterar och hashar det.
Lägger man på ett salt som är 14 tecken långt så har man ju förlängt lösenordet med 14 tecken, vilket gör att en brutal force kommer att ta 154,640,721,434 årtusenden att knäcka. Ett 5 tecken långt lösenord tar enbart 11 sekunder att knäcka om det innehåller bara små bokstäver (Källa di.se).
Saltet man lägger på är långt och har alla typer av tecken i sig, specialtecken, stora, små, siffror osv.
Saltet lagrar man INTE i databasen utan t.ex. så har man det som ett configvärde i web-config eller liknande.
På så sätt måste hackern få tag i både databas och web.config för att kunna ens fundera på att brutal forcea lösenordstabellen.
I många fall så är saltet variabelt, t.ex. så kan man använda det inmatade lösenordet för att modifiera saltet så att saltet är olika på alla lösenord men ändå återskapbara för den som vet hur man modifierat saltet.
Återkommer inom kort med hur man kryptear connectionstrings (även detta är en känd säkerhetsbrist inom programmering mot databaser)
MCPDn