Svenska
  • auth
  • lösenord
  • säkerhet
  • hashning
  • bcrypt
  • argon2
  • sha1
  • sha2
  • logga in
  • sign-in

Utvecklingen av lösenordshashning

Du har kanske hört råd om att välja lösenordshashningsalgoritmer, men har du tänkt på varför de rekommenderas? I den här artikeln kommer vi att utforska utvecklingen av lösenordshashningsalgoritmer och orsakerna bakom dem.

Gao
Gao
Founder

Introduktion

Lösenordshashning, som namnet antyder, är processen där ett hashvärde beräknas från ett lösenord. Hashvärdet lagras vanligtvis i en databas, och under inloggningsprocessen beräknas hashvärdet av lösenordet som användaren angav och jämförs med hashvärdet lagrat i databasen. Om de matchar, autentiseras användaren.

Innan vi dyker in i utvecklingen av lösenordshashningsalgoritmer är det viktigt att förstå varför det är nödvändigt.

Klartextlösenord: En stor säkerhetsrisk

Föreställ dig att du är användare av en webbplats där du har registrerat ett konto. En dag blir webbplatsen hackad och databasen läcks. Om webbplatsen lagrar lösenord i klartext kan hackaren direkt få tillgång till ditt lösenord. Eftersom många människor återanvänder lösenord över flera webbplatser kan hackaren använda detta lösenord för att få obehörig tillgång till dina andra konton. Situationen blir ännu värre om du använder samma eller ett liknande lösenord för ditt e-postkonto, eftersom hackaren kan återställa ditt lösenord och ta över alla dina associerade konton.

Även utan ett dataintrång kan alla med databasåtkomst inom stora team se lösenord. Jämfört med annan information är lösenord mycket känsliga och du vill definitivt inte att någon ska ha tillgång till dem.

Att lagra lösenord utan hashning är ett amatörmisstag. Tyvärr, om du söker efter "password leak plaintext", kommer du att upptäcka att stora företag som Facebook, DailyQuiz och GoDaddy har alla upplevt lösenordsläckor i klartext. Det är troligt att många andra företag har gjort samma misstag.

Kodning vs. kryptering vs. hashning

Dessa tre termer förväxlas ofta, men de är distinkta koncept.

Kodning

Kodning är det första att utesluta för lösenordslagring. Till exempel, Base64 är en kodningsalgoritm som konverterar binär data till en sträng av tecken:

Att känna till kodningsalgoritmen låter vem som helst avkoda den kodade strängen och återvinna den ursprungliga datan:

För hackare är de flesta kodningsalgoritmer motsvarigheter till klartext.

Kryptering

Innan hashning blev populärt användes kryptering för att lagra lösenord, som med AES. Kryptering innebär användning av en nyckel (eller ett par av nycklar) för att kryptera och dekryptera data.

Problemet med kryptering är uppenbart i termen "dekryptera". Kryptering är reversibelt, vilket betyder att om en hackare får tag i nyckeln kan de dekryptera lösenordet och återställa det till klartext.

Hashning

Den huvudsakliga skillnaden mellan hashning, kodning och kryptering är att hashning är irreversibelt. När ett lösenord har hashats kan det inte dekrypteras tillbaka till sin ursprungliga form.

Som webbplatsägare behöver du faktiskt inte veta lösenordet självt, så länge som användaren kan logga in med rätt lösenord. Registreringsprocessen kan förenklas enligt följande:

  1. Användaren anger lösenordet.
  2. Tjänsten använder en hashningsalgoritm för att beräkna hashvärdet av lösenordet.
  3. Tjänsten lagrar hashvärdet i databasen.

När användaren loggar in går processen till så här:

  1. Användaren anger lösenordet.
  2. Tjänsten använder samma hashningsalgoritm för att beräkna hashvärdet av lösenordet.
  3. Tjänsten jämför hashvärdet med hashvärdet lagrat i databasen.
  4. Om hashvärdena matchar, autentiseras användaren.

Båda processerna undviker att lagra lösenord i klartext, och eftersom hashning är irreversibel, även om databasen komprometteras kan hackaren endast få tag i hashvärden som framstår som slumpmässiga strängar.

Hashningsalgoritmer startpaket

Hashning kan verka som den perfekta lösningen för lösenordslagring, men det är inte så enkelt. För att förstå varför, låt oss utforska utvecklingen av lösenordshashningsalgoritmer.

MD5

1992 designade Ron Rivest MD5-algoritmen, en meddelandebearbetningsalgoritm som kan beräkna ett 128-bitars hashvärde från vilken data som helst. MD5 har använts i olika fält, inklusive lösenordshashning. Till exempel är MD5-hashvärdet av "123456":

Som nämnts tidigare, framstår hashvärdet som en slumpmässig sträng och är irreversibelt. Dessutom är MD5 snabb och lätt att implementera, vilket gör den till den mest populära lösenordshashningsalgoritmen.

Men MD5:s fördelar är även dess svagheter inom lösenordshashning. Dess snabbhet gör den sårbar för brute-force-attacker. Om en hackare har en lista över vanliga lösenord och din personliga information kan de beräkna MD5-hashvärdena för varje kombination och jämföra dem med hashvärdena i databasen. Till exempel kan de kombinera din födelsedag med ditt namn eller ditt husdjurs namn.

Idag är datorer betydligt kraftfullare än tidigare, vilket gör det lätt att brute force MD5-lösenordshashningar.

SHA-familjen

Så varför inte använda en annan algoritm som genererar längre hashvärden? SHA-familjen verkar som ett bra val. SHA-1 är en hashningsalgoritm som genererar 160-bitars hashvärden, och SHA-2 är en familj av hashningsalgoritmer som genererar hashvärden på 224-bit, 256-bit, 384-bit och 512-bit längder. Låt oss se SHA-256-hashvärdet av "123456":

SHA-256-hashvärdet är mycket längre än MD5 och är också irreversibelt. Det finns dock ett annat problem: om du redan känner till hashvärdet, som det ovan, och du ser exakt samma hashvärde i databasen, vet du att lösenordet är "123456". En hackare kan skapa en lista över vanliga lösenord och deras motsvarande hashvärden och jämföra dem mot hashvärdena i databasen. Denna lista är känd som en regnbågstabell.

Salt

För att motverka regnbågstabellsattacker introducerades konceptet salt. Salt är en slumpmässig sträng som läggs till lösenordet innan hashning. Till exempel, om saltet är "salt", och du vill använda SHA-256 för att hasha lösenordet "123456" med saltet, istället för att helt enkelt göra:

Skulle du göra:

Som du kan se, är resultatet helt annorlunda än hashning utan salt. Typiskt ges varje användare ett slumpmässigt salt under registrering, som lagras i databasen tillsammans med hashvärdet. Under inloggningsprocessen används saltet för att beräkna hashvärdet av det angivna lösenordet, vilket sedan jämförs med det lagrade hashvärdet.

Iteration

Trots tillsatsen av salt är hashvärdet fortfarande känsligt för brute-force-attacker eftersom hårdvara blir kraftfullare. För att göra det svårare kan iteration (dvs att köra hashningsalgoritmen flera gånger) introduceras. Till exempel, istället för att använda:

Skulle du använda:

Genom att öka antalet iterationer görs brute-forcing svårare. Detta påverkar dock även inloggningsprocessen eftersom det blir långsammare. Därför måste en balans mellan säkerhet och prestanda uppnås.

Halvtidspaus

Låt oss ta en paus och sammanfatta egenskaperna hos en bra lösenordshashningsalgoritm:

  • Irreversibel (preimage-resistens)
  • Svårt att brute force
  • Motståndskraftig mot regnbågstabellsattacker

Som du kanske har märkt är salt och iteration nödvändiga för att uppfylla alla dessa krav. Problemet är att både MD5 och SHA-familjen inte specifikt designades för lösenordshashning; de används i stor utsträckning för integritetskontroller (eller "meddelandebearbetning"). Därför kan varje webbplats ha sin egen implementation av salt och iteration, vilket gör standardisering och migrering utmanande.

Lösenordshashningsalgoritmer

För att lösa detta problem har flera hashningsalgoritmer specifikt designats för lösenordshashning. Låt oss titta på några av dem.

bcrypt

bcrypt är en lösenordshashningsalgoritm designad av Niels Provos och David Mazières. Den används i stor utsträckning i många programmeringsspråk. Här är ett exempel på bcrypt-hashvärde:

Även om det verkar som en annan slumpmässig sträng, innehåller det ytterligare information. Låt oss bryta ner det:

  • Den första sektionen $2y anger algoritmen, som är 2y.
  • Den andra sektionen $12 anger antalet iterationer, vilket är 12. Detta betyder att hashingsalgoritmen kommer att köras 212=4096 gånger (iterationer).
  • Den tredje sektionen wNt7lt/xf8wRJgPU7kK2ju är saltet.
  • Den sista sektionen GrirhHK4gdb0NiCRdsSoAxqQoNbiluu är hashvärdet.

bcrypt har vissa begränsningar:

  • Den maximala längden på lösenordet är 72 byte.
  • Saltet är begränsat till 16 byte.
  • Hashvärdet är begränsat till 184 bitar.

Argon2

Med tanke på debatterna och begränsningarna hos befintliga lösenordshashningsalgoritmer hölls en lösenordshashningstävling 2015. Utan att gå in på detaljer, låt oss fokusera på vinnaren: Argon2.

Argon2 är en lösenordshashningsalgoritm designad av Alex Biryukov, Daniel Dinu och Dmitry Khovratovich. Den introducerar flera nya koncept:

  • Minneshård: Algoritmen är designad att vara svår att parallellisera, vilket gör brute-forcing med GPU:er utmanande.
  • Tidskrävande: Algoritmen är designad att vara svår att optimera, vilket gör brute-forcing med ASIC:ar (Application-specific integrated circuits) svårt.
  • Sidokanalresistent: Algoritmen är designad att vara resistent mot sidokanalattacker, såsom tidsattacker.

Det finns två huvudversioner av Argon2, Argon2i och Argon2d. Argon2i är den säkraste mot sidokanalattacker, medan Argon2d ger högsta motståndskraft mot GPU-crackingattacker.

-- Argon2

Här är ett exempel på ett Argon2-hashvärde:

Låt oss bryta ner det:

  • Den första sektionen $argon2i anger algoritmen, som är argon2i.
  • Den andra sektionen $v=19 anger versionen, som är 19.
  • Den tredje sektionen $m=16,t=2,p=1 anger minneskostnad, tidskostnad, och parallellismsgrad, vilket är 16, 2, och 1.
  • Den fjärde sektionen $YTZ5ZnpXRWN5SlpjMHBDRQ är saltet.
  • Den sista sektionen $12oUmJ6xV5bIadzZHkuLTg är hashvärdet.

I Argon2 är den maximala längden på lösenordet 232-1 byte, saltet är begränsat till 232-1 byte, och hashvärdet är begränsat till 232-1 byte. Detta borde räcka för de flesta scenarier.

Argon2 är nu tillgänglig i många programmeringsspråk, som node-argon2 för Node.js och argon2-cffi för Python.

Slutsats

Under åren har lösenordshashningsalgoritmer genomgått betydande utveckling. Vi står i skuld till säkerhetsgemenskapen för deras decennier av insatser för att göra internet till en säkrare plats. Tack vare deras bidrag kan utvecklare ägna mer uppmärksamhet åt att bygga bättre tjänster utan att oroa sig för säkerheten kring lösenordshashning. Även om det kan vara ouppnåeligt att uppnå 100 % säkerhet i ett system, kan vi använda olika strategier för att minimera de associerade riskerna.

Om du vill undvika krånglet med att implementera autentisering och auktorisering, känn dig fri att prova Logto gratis. Vi erbjuder säkra (vi använder Argon2!), tillförlitliga och skalbara lösningar, vilket gör det möjligt för dig att fokusera på att bygga din produkt.