Generirajte sigurnu slučajnu lozinku na 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. Uvod

U ovom ćemo uputstvu pogledati razne metode koje možemo koristiti za generiranje sigurne slučajne lozinke u Javi.

U našim ćemo primjerima generirati lozinke od deset znakova, svaka s najmanje dva mala slova, dva velika slova, dvije znamenke i dva posebna znaka.

2. Korištenje Passaya

Passay je knjižnica za provođenje pravila zaporke. Značajno je da knjižnicu možemo koristiti za generiranje lozinke pomoću podesivog skupa pravila.

Uz pomoć zadane Podaci o liku implementacije, možemo formulirati pravila potrebna za lozinku. Nadalje, možemo formulirati običaj Podaci o liku implementacije koje odgovaraju našim zahtjevima:

javni String generirajPassayPassword () {PasswordGenerator gen = novi PasswordGenerator (); CharacterData lowerCaseChars = EnglishCharacterData.LowerCase; CharacterRule lowerCaseRule = novo CharacterRule (lowerCaseChars); lowerCaseRule.setNumberOfCharacters (2); CharacterData upperCaseChars = EnglishCharacterData.UpperCase; CharacterRule upperCaseRule = novo CharacterRule (upperCaseChars); upperCaseRule.setNumberOfCharacters (2); CharacterData digitChars = EnglishCharacterData.Digit; CharacterRule digitRule = novo CharacterRule (digitChars); digitRule.setNumberOfCharacters (2); CharacterData specialChars = novi CharacterData () {javni niz getErrorCode () {return ERROR_CODE; } javni String getCharacters () {return "[zaštićen e-poštom] # $% ^ & * () _ +"; }}; CharacterRule splCharRule = novo CharacterRule (specialChars); splCharRule.setNumberOfCharacters (2); Lozinka niza = gen.generatePassword (10, splCharRule, lowerCaseRule, upperCaseRule, digitRule); vratiti lozinku; }

Evo, stvorili smo običaj Podaci o liku implementacija za posebne znakove. To nam omogućuje da ograničimo skup valjanih dopuštenih znakova.

Osim toga, koristimo zadane implementacije Podaci o liku za naša druga pravila.

Sada, provjerimo naš generator prema jediničnom testu. Na primjer, možemo provjeriti prisutnost dva posebna znaka:

@Test public void whenPasswordGeneratedUsingPassay_thenSuccessful () {RandomPasswordGenerator passGen = novi RandomPasswordGenerator (); Lozinka niza = passGen.generatePassayPassword (); int specialCharCount = 0; za (char c: password.toCharArray ()) ako je (c> = 33 

Vrijedno je to napomenuti iako je Passay otvoreni izvor, dvostruko je licenciran i pod LGPL i Apache 2. Kao i kod bilo kojeg softvera treće strane, moramo biti sigurni da se pridržavamo ovih licenci kada ga koristimo u našim proizvodima. Web stranica GNU sadrži više informacija o LGPL i Javi.

3. Korištenje RandomStringGenerator

Dalje, pogledajmo RandomStringGenerator u Apache Commons Text. S RandomStringGenerator, možemo generirati Unicode nizove koji sadrže navedeni broj kodnih točaka.

Sada ćemo stvoriti instancu generatora pomoću RandomStringGenerator.Builder razred. Naravno, također možemo dodatno manipulirati svojstvima generatora.

Uz pomoć graditelja lako možemo promijeniti zadanu implementaciju slučajnosti. Štoviše, možemo definirati i znakove koji su dopušteni u nizu:

javni String generirajRandomSpecialCharacters (int dužina) {RandomStringGenerator pwdGenerator = novi RandomStringGenerator.Builder (). WithinRange (33, 45) .build (); return pwdGenerator.generate (length); } 

Sada, jedno ograničenje upotrebe RandomStringGenerator je li to to nema mogućnost određivanja broja znakova u svakom skupu, kao u Passayu. Međutim, to možemo zaobići spajanjem rezultata više skupova:

javni String generirajCommonTextPassword () {Niz pwString = generirajRandomSpecialCharacters (2) .concat (generirajRandomNumbers (2)) .concat (generirajRandomAlphabet (2, istina)) .concat (generirajRandomAlphabet (2, lažno)) .concat (generirajRandom) Popis pwChars = pwString.chars () .mapToObj (podaci -> (char) podaci) .collect (Collectors.toList ()); Collections.shuffle (pwChars); Lozinka niza = pwChars.stream () .collect (StringBuilder :: new, StringBuilder :: append, StringBuilder :: append) .toString (); vratiti lozinku; }

Dalje, provjerimo generiranu lozinku provjerom malih slova:

@Test public void whenPasswordGeneratedUsingCommonsText_thenSuccessful () {RandomPasswordGenerator passGen = novi RandomPasswordGenerator (); Lozinka niza = passGen.generateCommonTextPassword (); int lowerCaseCount = 0; za (char c: password.toCharArray ()) 

Prema zadanim postavkama, RandomStringGenerator koristi ThreadLocalRandom za slučajnost. Sada je važno spomenuti da ovo ne osigurava kriptografsku sigurnost.

Međutim, izvor slučajnosti možemo postaviti pomoću usingRandom (TextRandomProvider). Na primjer, možemo se poslužiti SecureTextRandomProvider za kriptografsku sigurnost:

javni niz generiraRandomSpecialCharacters (int dužina) {SecureTextRandomProvider stp = novi SecureTextRandomProvider (); RandomStringGenerator pwdGenerator = novi RandomStringGenerator.Builder () .withinRange (33, 45) .usingRandom (stp) .build (); return pwdGenerator.generate (length); }

4. Korištenje RandomStringUtils

Druga mogućnost koju bismo mogli zaposliti je RandomStringUtils razreda u biblioteci Apache Commons Lang. Ova klasa izlaže nekoliko statičnih metoda koje možemo koristiti za izradu problema.

Pogledajmo kako možemo pružiti raspon kodnih točaka prihvatljivih za lozinku:

 javni String generatedCommonLangPassword () {String upperCaseLetters = RandomStringUtils.random (2, 65, 90, true, true); Niz lowerCaseLetters = RandomStringUtils.random (2, 97, 122, true, true); Brojevi nizova = RandomStringUtils.randomNumeric (2); String specialChar = RandomStringUtils.random (2, 33, 47, false, false); Niz totalChars = RandomStringUtils.randomAlfhanumeric (2); Niz kombinacijiChars = upperCaseLetters.concat (lowerCaseLetters) .concat (brojevi) .concat (specialChar) .concat (totalChars); Popis pwdChars = kombinacijiChars.chars () .mapToObj (c -> (char) c) .collect (Collectors.toList ()); Collections.shuffle (pwdChars); Lozinka niza = pwdChars.stream () .collect (StringBuilder :: new, StringBuilder :: append, StringBuilder :: append) .toString (); vratiti lozinku; }

Da bismo provjerili generiranu lozinku, provjerimo brojčani broj:

@Test public void whenPasswordGeneratedUsingCommonsLang3_thenSuccessful () {RandomPasswordGenerator passGen = novi RandomPasswordGenerator (); Lozinka niza = passGen.generateCommonsLang3Password (); int numCount = 0; za (char c: password.toCharArray ()) 

Ovdje, RandomStringUtils koristi Slučajno po defaultu kao izvor slučajnosti. Međutim, u biblioteci postoji metoda koja nam omogućuje da odredimo izvor slučajnosti:

String lowerCaseLetters = RandomStringUtils. random (2, 97, 122, true, true, null, novo SecureRandom ());

Sada bismo mogli osigurati kriptografsku sigurnost pomoću instance SecureRandom. Međutim, ovu se funkcionalnost ne može proširiti na druge metode u knjižnici. U napomeni, Apache zagovara upotrebu RandomStringUtils samo za jednostavne slučajeve uporabe.

5. Korištenje prilagođene korisne metode

Također možemo iskoristiti SecureRandom klase za stvaranje prilagođene klase uslužnih programa za naš scenarij. Za početak, generirajmo niz posebnih znakova duljine dvije:

javni tok getRandomSpecialChars (int count) {Slučajni slučajni = novi SecureRandom (); IntStream specialChars = random.ints (count, 33, 45); vratiti specialChars.mapToObj (podaci -> (char) podaci); }

Također, primijetite to 33 i 45 označavaju raspon Unicode znakova. Sada možemo generirati više tokova prema našim zahtjevima. Tada možemo spojiti skupove rezultata kako bismo generirali potrebnu lozinku:

javni String generišeSecureRandomPassword () {Stream pwdStream = Stream.concat (getRandomNumbers (2), Stream.concat (getRandomSpecialChars (2), Stream.concat (getRandomAlphabets (2, true), getRandomAlphabets (4, false)) Popis charList = pwdStream.collect (Collectors.toList ()); Collections.shuffle (charList); Lozinka niza = charList.stream () .collect (StringBuilder :: new, StringBuilder :: append, StringBuilder :: append) .toString (); vratiti lozinku; } 

Sada provjerimo generiranu lozinku za broj posebnih znakova:

@Test public void whenPasswordGeneratedUsingSecureRandom_thenSuccessful () {RandomPasswordGenerator passGen = novi RandomPasswordGenerator (); Lozinka niza = passGen.generateSecureRandomPassword (); int specialCharCount = 0; za (char c: password.toCharArray ()) c = 2); 

6. Zaključak

U ovom vodiču uspjeli smo generirati lozinke, u skladu s našim zahtjevima, koristeći različite knjižnice.

Kao i uvijek, uzorci koda korišteni u članku dostupni su 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