Hashing lozinke u Javi

Java Top

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ

1. Pregled

U ovom uputstvu razgovarat ćemo o važnosti raspršivanja lozinke.

Kratko ćemo pogledati što je to, zašto je to važno i neke sigurne i nesigurne načine za to na Javi.

2. Što se raspršuje?

Hashing je postupak generiranja niza, ili hash, iz datog poruka pomoću matematičke funkcije poznate kao a kriptografska hash funkcija.

Iako postoji nekoliko hash funkcija, one prilagođene hashiranju lozinki moraju imati četiri glavna svojstva da bi bile sigurne:

  1. Trebalo bi biti deterministički: ista poruka koju obrađuje ista hash funkcija treba stalno proizvesti isto hash
  2. Nije reverzibilan: nepraktično je generirati poruka iz svog hash
  3. Ima visoku entropija: mala promjena u a poruka treba proizvesti potpuno drugačiji hash
  4. I opire se sudara: dva različita poruke ne bi trebali proizvoditi isto hash

Funkcija raspršivanja koja ima sva četiri svojstva snažan je kandidat za raspršivanje lozinke, jer zajedno dramatično povećavaju poteškoće u obrnutom inženjeringu lozinke iz raspršivača.

Također, međutim, funkcije raspršivanja lozinke trebaju biti spore. Pomogao bi brzi algoritam sirova snaga napadi u kojima će haker pokušati pogoditi lozinku raspršivanjem i uspoređivanjem milijardi (ili bilijuna) potencijalnih lozinki u sekundi.

Neke su sjajne hash funkcije koje udovoljavaju svim tim kriterijimaPBKDF2, BCrypt, i Skriptiraj. Ali prvo, pogledajmo neke starije algoritme i zašto se više ne preporučuju

3. Ne preporučuje se: MD5

Naša prva hash funkcija je MD5 algoritam za sabiranje poruka, razvijen davne 1992. godine.

Java MessageDigest olakšava izračunavanje i još uvijek može biti korisno u drugim okolnostima.

Međutim, tijekom posljednjih nekoliko godina, Otkriveno je da MD5 nije uspio četvrto svojstvo raspršivanja lozinke u tome što je računski postalo lako generirati sudare. Povrh svega, MD5 je brzi algoritam i stoga beskoristan protiv napada grubom silom.

Zbog njih se MD5 ne preporučuje.

4. Ne preporučuje se: SHA-512

Dalje ćemo pogledati SHA-512, koji je dio obitelji Secure Hash Algorithm, obitelji koja je započela sa SHA-0 davne 1993. godine.

4.1. Zašto SHA-512?

Kako se računala povećavaju, a kako pronalazimo nove ranjivosti, istraživači izvode nove verzije SHA. Novije verzije imaju postupno sve veću duljinu, ili ponekad istraživači objavljuju novu verziju osnovnog algoritma.

SHA-512 predstavlja najduži ključ u trećoj generaciji algoritma.

Dok sada postoje sigurnije verzije SHA, SHA-512 je najjači koji je implementiran u Javi.

4.2. Implementacija u Javi

Sada, pogledajmo primjenu algoritma hashiranja SHA-512 u Javi.

Prvo, moramo razumjeti koncept sol. Jednostavno rečeno, ovo je slučajni niz koji se generira za svako novo raspršivanje.

Uvođenjem ove slučajnosti povećavamo hash-ove entropija, a mi štitimo našu bazu podataka od unaprijed sastavljenih popisa heša poznatih kao dugini stolovi.

Naša nova hash funkcija tada postaje otprilike:

sol <- generirati-sol; hash <- sol + ':' + sha512 (sol + lozinka)

4.3. Stvaranje soli

Za uvođenje soli koristit ćemo SecureRandom razred iz java.sigurnost:

SecureRandom random = novo SecureRandom (); bajt [] sol = novi bajt [16]; random.nextBytes (sol);

Zatim ćemo upotrijebiti MessageDigest klasa za konfiguriranje SHA-512 hash funkcija s našom soli:

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

I s tim dodanim, sada možemo koristiti probaviti metoda za generiranje naše raspršene lozinke:

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

4.4. Zašto se ne preporučuje?

Kada se koristi sa soli, SHA-512 je i dalje poštena opcija, ali vani postoje jače i sporije opcije.

Također, preostale opcije koje ćemo pokriti imaju važnu značajku: podesivu snagu.

5. PBKDF2, BCrypt i SCrypt

PBKDF2, BCrypt i SCrypt tri su preporučena algoritma.

5.1. Zašto se preporučuju?

Svaki od njih je spor i svaki ima briljantnu značajku konfigurabilne snage.

To znači da kako računala povećavaju snagu, možemo usporiti algoritam promjenom ulaza.

5.2. Implementacija PBKDF2 u Javi

Sada, soli su temeljno načelo raspršivanja lozinke, pa nam je potreban i za PBKDF2:

SecureRandom random = novo SecureRandom (); bajt [] sol = novi bajt [16]; random.nextBytes (sol);

Dalje ćemo stvoriti PBEKeySpec i a SecretKeyFactory koju ćemo instancirati pomoću PBKDF2SHmacSHA1 algoritam:

KeySpec spec = novi PBEKeySpec (password.toCharArray (), sol, 65536, 128); Tvornica SecretKeyFactory = SecretKeyFactory.getInstance ("PBKDF2WithHmacSHA1");

Treći parametar (65536) je efektivno parametar čvrstoće. Označava za koliko iteracija se pokreće ovaj algoritam, povećavajući vrijeme potrebno za stvaranje hasha.

Napokon, možemo se poslužiti našim SecretKeyFactory za generiranje hasha:

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

5.3. Implementacija BCrypt i SCrypt u Javi

Pa, ispada da Podrška za BCrypt i SCrypt još se ne isporučuju s Javom, iako ih neke Java knjižnice podržavaju.

Jedna od tih knjižnica je Spring Security.

6. Hashing lozinke s proljetnom sigurnošću

Iako Java izvorno podržava i algoritme za raspršivanje PBKDF2 i SHA, ne podržava BCrypt i SCrypt algoritme.

Srećom po nas, Spring Security isporučuje podršku za sve ove preporučene algoritme putem PasswordEncoder sučelje:

  • MessageDigestPasswordEncoder daje nam MD5 i SHA-512
  • Pbkdf2PasswordEncoder daje nam PBKDF2
  • BCryptPasswordEncoder daje nam BCrypt i
  • SCryptPasswordEncoder daje nam SCrypt

Kodiranje lozinki za PBKDF2, BCrypt i SCrypt dolazi s podrškom za konfiguriranje željene snage hasha lozinke.

Te kodere možemo koristiti izravno, čak i bez aplikacije temeljene na Spring Security. Ili, ako svoju web stranicu štitimo Spring Springom, tada možemo konfigurirati željeni koder lozinke putem DSL-a ili putem ubrizgavanja ovisnosti.

I, za razliku od naših gornjih primjera, ovi algoritmi šifriranja interno će generirati sol za nas. Algoritam pohranjuje sol unutar izlaznog hasha za kasniju upotrebu u provjeri valjanosti lozinke.

7. Zaključak

Dakle, duboko smo zarobili u raspršivanje lozinke; istraživanje pojma i njegove upotrebe.

Pogledali smo neke povijesne hash funkcije kao i neke trenutno implementirane prije nego što smo ih kodirali u Javi.

Konačno, vidjeli smo da se Spring Security isporučuje sa svojim klasama šifriranja lozinke, implementirajući niz različitih hash funkcija.

Kao i uvijek, kôd je dostupan na GitHubu.

Dno Java

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ