Hashing et passord i Java

Java Top

Jeg kunngjorde nettopp det nye Lær våren kurs, med fokus på det grunnleggende i vår 5 og vårstøvel 2:

>> KONTROLLER KURSET

1. Oversikt

I denne opplæringen vil vi diskutere viktigheten av passordhashing.

Vi tar en rask titt på hva det er, hvorfor det er viktig, og noen sikre og usikre måter å gjøre det på Java.

2. Hva er Hashing?

Hashing er prosessen med å generere en streng, eller hasj, fra en gitt beskjed ved hjelp av en matematisk funksjon kjent som a kryptografisk hash-funksjon.

Mens det er flere hash-funksjoner der ute, må de som er skreddersydd for hashing-passord ha fire hovedegenskaper for å være sikre:

  1. Det bør være deterministisk: den samme meldingen behandlet av den samme hash-funksjonen skal alltid produsere det samme hasj
  2. Det er ikke reversibel: det er upraktisk å generere en beskjed fra sin hasj
  3. Den har høy entropi: en liten endring til en beskjed burde produsere et veldig annet hasj
  4. Og den motstår kollisjoner: to forskjellige meldinger skal ikke produsere det samme hasj

En hash-funksjon som har alle de fire egenskapene er en sterk kandidat for passordhashing siden de sammen dramatisk øker vanskeligheten med å reverse-engineering passordet fra hash.

Også, skjønt, funksjoner for passordhashing bør være treg. En rask algoritme vil hjelpe Ren styrke angrep der en hacker vil prøve å gjette et passord ved å haske og sammenligne milliarder (eller trillioner) potensielle passord per sekund.

Noen gode hashfunksjoner som oppfyller alle disse kriteriene erPBKDF2, BCrypt, og SCrypt. Men først, la oss ta en titt på noen eldre algoritmer og hvorfor de ikke lenger anbefales

3. Ikke anbefalt: MD5

Vår første hash-funksjon er MD5-meldingsfordøyelsesalgoritmen, utviklet helt tilbake i 1992.

Java MessageDigest gjør dette enkelt å beregne og kan fortsatt være nyttig under andre omstendigheter.

I løpet av de siste årene har MD5 ble oppdaget for å mislykkes i den fjerde passordhash-egenskapen ved at det ble beregningsmessig enkelt å generere kollisjoner. På toppen av det er MD5 en rask algoritme og derfor ubrukelig mot brutale kraftangrep.

På grunn av disse anbefales ikke MD5.

4. Ikke anbefalt: SHA-512

Deretter ser vi på SHA-512, som er en del av Secure Hash Algorithm-familien, en familie som begynte med SHA-0 tilbake i 1993.

4.1. Hvorfor SHA-512?

Når datamaskiner øker kraften, og når vi finner nye sårbarheter, får forskere nye versjoner av SHA. Nyere versjoner har gradvis lengre lengde, eller noen ganger publiserer forskere en ny versjon av den underliggende algoritmen.

SHA-512 representerer den lengste nøkkelen i tredje generasjon av algoritmen.

Samtidig som det er nå sikrere versjoner av SHA, SHA-512 er den sterkeste som er implementert i Java.

4.2. Implementering i Java

La oss nå ta en titt på implementering av SHA-512 hashing-algoritmen i Java.

Først må vi forstå begrepet salt. For å si det enkelt, dette er en tilfeldig sekvens som genereres for hver nye hash.

Ved å innføre denne tilfeldigheten øker vi hasjene entropi, og vi beskytter databasen vår mot forhåndskompilerte lister med hashes kjent som regnbuebord.

Vår nye hash-funksjon blir da omtrent:

salt <- generer-salt; hash <- salt + ':' + sha512 (salt + passord)

4.3. Å generere et salt

For å introdusere salt bruker vi SecureRandom klasse fra java.sikkerhet:

SecureRandom random = new SecureRandom (); byte [] salt = ny byte [16]; random.nextBytes (salt);

Så bruker vi MessageDigest klasse for å konfigurere SHA-512 hasjfunksjon med saltet vårt:

MessageDigest md = MessageDigest.getInstance ("SHA-512"); md.update (salt);

Og med det lagt til, kan vi nå bruke fordøye metode for å generere vårt hashede passord:

byte [] hashedPassword = md.digest (passwordToHash.getBytes (StandardCharsets.UTF_8));

4.4. Hvorfor anbefales det ikke?

Når det brukes med salt, er SHA-512 fortsatt et greit alternativ, men det er sterkere og langsommere alternativer der ute.

Også de gjenværende alternativene vi dekker har en viktig funksjon: konfigurerbar styrke.

5. PBKDF2, BCrypt og SCrypt

PBKDF2, BCrypt og SCrypt er tre anbefalte algoritmer.

5.1. Hvorfor anbefales de?

Hver av disse er treg, og hver har den strålende funksjonen å ha en konfigurerbar styrke.

Dette betyr at når datamaskiner øker i styrke, vi kan bremse algoritmen ved å endre inngangene.

5.2. Implementering av PBKDF2 i Java

Nå, salter er et grunnleggende prinsipp for passordhashing, og så trenger vi også en for PBKDF2:

SecureRandom random = new SecureRandom (); byte [] salt = ny byte [16]; random.nextBytes (salt);

Deretter oppretter vi en PBEKeySpec og en SecretKeyFactory som vi vil instantiere ved hjelp av PBKDF2WithHmacSHA1 algoritme:

KeySpec spec = ny PBEKeySpec (password.toCharArray (), salt, 65536, 128); SecretKeyFactory fabrikk = SecretKeyFactory.getInstance ("PBKDF2WithHmacSHA1");

Den tredje parameteren (65536) er effektivt styrkeparameteren. Det indikerer hvor mange iterasjoner denne algoritmen kjører for, og øker tiden det tar å produsere hasjen.

Endelig kan vi bruke vår SecretKeyFactory å generere hash:

byte [] hash = factory.generateSecret (spec) .getEncoded ();

5.3. Implementering av BCrypt og SCrypt i Java

Så det viser seg at BCrypt og SCrypt-støtte leveres ikke med Java ennå, selv om noen Java-biblioteker støtter dem.

En av disse bibliotekene er Spring Security.

6. Passordhassing med vårsikkerhet

Selv om Java naturlig støtter både PBKDF2- og SHA-hashingalgoritmene, støtter den ikke BCrypt- og SCrypt-algoritmer.

Heldigvis for oss leveres Spring Security med støtte for alle disse anbefalte algoritmene via PasswordEncoder grensesnitt:

  • MessageDigestPasswordEncoder gir oss MD5 og SHA-512
  • Pbkdf2PasswordEncoder gir oss PBKDF2
  • BCryptPasswordEncoder gir oss BCrypt, og
  • SCryptPasswordEncoder gir oss SCrypt

Passordkoderne for PBKDF2, BCrypt og SCrypt kommer alle med støtte for å konfigurere ønsket styrke for passordhash.

Vi kan bruke disse koderne direkte, selv uten å ha et Spring Security-basert program. Eller hvis vi beskytter nettstedet vårt med Spring Security, kan vi konfigurere ønsket passordkoder gjennom DSL eller via avhengighetsinjeksjon.

Og i motsetning til eksemplene våre ovenfor, disse krypteringsalgoritmene vil generere saltet internt for oss. Algoritmen lagrer saltet i utgangshashen for senere bruk for validering av passord.

7. Konklusjon

Så vi har tatt et dypt dykk i passordhashing; utforske konseptet og dets bruksområder.

Og vi har sett på noen historiske hash-funksjoner, så vel som noen som er implementert for øyeblikket, før vi koder dem i Java.

Til slutt så vi at Spring Security leveres med passordkrypteringsklasser, og implementerer en rekke forskjellige hashfunksjoner.

Som alltid er koden tilgjengelig på GitHub.

Java bunn

Jeg kunngjorde nettopp det nye Lær våren kurs, med fokus på det grunnleggende i vår 5 og vårstøvel 2:

>> KONTROLLER KURSET

$config[zx-auto] not found$config[zx-overlay] not found