Hashing lozinke u Javi
Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:
>> PROVJERITE TEČAJ1. 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:
- Trebalo bi biti deterministički: ista poruka koju obrađuje ista hash funkcija treba stalno proizvesti isto hash
- Nije reverzibilan: nepraktično je generirati poruka iz svog hash
- Ima visoku entropija: mala promjena u a poruka treba proizvesti potpuno drugačiji hash
- 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