Vytvorte bezpečné náhodné heslo v prostredí Java

Java Top

Práve som oznámil nové Naučte sa jar kurz zameraný na základy jari 5 a Spring Boot 2:

>> SKONTROLUJTE KURZ

1. Úvod

V tomto výučbe sa pozrieme na rôzne metódy, ktoré môžeme použiť na generovanie bezpečného náhodného hesla v Jave.

V našich príkladoch budeme generovať desaťmiestne heslá, každé s minimálne dvoma malými písmenami, dvoma veľkými písmenami, dvoma číslicami a dvoma špeciálnymi znakmi.

2. Používanie Passay

Passay je knižnica na presadzovanie politiky hesla. Predovšetkým môžeme využiť knižnicu na generovanie hesla pomocou konfigurovateľnej sady pravidiel.

Pomocou predvoleného nastavenia CharacterData implementácie, môžeme formulovať pravidlá požadované pre heslo. Ďalej môžeme formulovať zvyk CharacterData implementácie tak, aby vyhovovali našim požiadavkám:

public String generatePassayPassword () {PasswordGenerator gen = new PasswordGenerator (); CharacterData lowerCaseChars = EnglishCharacterData.LowerCase; CharacterRule lowerCaseRule = nové CharacterRule (lowerCaseChars); lowerCaseRule.setNumberOfCharacter (2); CharacterData upperCaseChars = EnglishCharacterData.UpperCase; CharacterRule upperCaseRule = nové CharacterRule (upperCaseChars); upperCaseRule.setNumberOfCharacter (2); CharacterData digitChars = EnglishCharacterData.Digit; CharacterRule digitRule = nové CharacterRule (digitChars); digitRule.setNumberOfCharacters (2); CharacterData specialChars = new CharacterData () {public String getErrorCode () {return ERROR_CODE; } public String getCharacter () {návrat "[chránený e-mailom] # $% ^ & * () _ +"; }}; CharacterRule splCharRule = nové CharacterRule (specialChars); splCharRule.setNumberOfCharacters (2); Reťazcové heslo = gen.generatePassword (10, splCharRule, lowerCaseRule, upperCaseRule, digitRule); návratové heslo; }

Tu sme vytvorili zvyk CharacterData implementácia pre špeciálne znaky. To nám umožňuje obmedziť skupinu povolených platných znakov.

Okrem toho využívame predvolené implementácie CharacterData pre naše ďalšie pravidlá.

Teraz skontrolujme náš generátor proti testu jednotky. Napríklad môžeme skontrolovať prítomnosť dvoch špeciálnych znakov:

@Test public void whenPasswordGeneratedUsingPassay_thenSuccessful () {RandomPasswordGenerator passGen = nový RandomPasswordGenerator (); Reťazcové heslo = passGen.generatePassayPassword (); int specialCharCount = 0; pre (char c: password.toCharArray ()) if (c> = 33 

Stojí za zmienku, že Aj keď je Passay otvorený zdroj, má dvojitú licenciu LGPL aj Apache 2. Rovnako ako v prípade iného softvéru tretích strán, musíme si byť istí, že dodržujeme tieto licencie, keď ho používame v našich produktoch. Web GNU obsahuje viac informácií o LGPL a Jave.

3. Používanie RandomStringGenerator

Ďalej sa pozrime na RandomStringGenerator v texte Apache Commons. S RandomStringGenerator, môžeme vygenerovať reťazce Unicode obsahujúce zadaný počet kódových bodov.

Teraz vytvoríme inštanciu generátora pomocou RandomStringGenerator.Builder trieda. S vlastnosťami generátora samozrejme môžeme ďalej manipulovať.

Pomocou staviteľa môžeme ľahko zmeniť predvolenú implementáciu náhodnosti. Ďalej môžeme definovať aj znaky, ktoré sú v reťazci povolené:

public String generateRandomSpecialCharacters (int dĺžka) {RandomStringGenerator pwdGenerator = nový RandomStringGenerator.Builder (). withinRange (33, 45) .build (); návrat pwdGenerator.generate (dĺžka); } 

Teraz jedno obmedzenie používania RandomStringGenerator je to ono chýba schopnosť určiť počet znakov v každej sade, napríklad v Passay. Môžeme to však obísť zlúčením výsledkov viacerých množín:

public String generateCommonTextPassword () {String pwString = generateRandomSpecialCharacters (2) .concat (generateRandomNumbers (2)) .concat (generateRandomAlphabet (2, true)) .concat (generateRandomAlphabet (2, false)) .concat (generateRandomCharacters (2)); Zoznam pwChars = pwString.chars () .mapToObj (údaje -> (char) údaje) .collect (Collectors.toList ()); Zbierky.shuffle (pwChars); Reťazcové heslo = pwChars.stream () .collect (StringBuilder :: new, StringBuilder :: append, StringBuilder :: append) .toString (); návratové heslo; }

Ďalej overíme vygenerované heslo overením malých písmen:

@Test public void whenPasswordGeneratedUsingCommonsText_thenSuccessful () {RandomPasswordGenerator passGen = nový RandomPasswordGenerator (); Reťazec heslo = passGen.generateCommonTextPassword (); int lowerCaseCount = 0; pre (char c: password.toCharArray ()) 

Predvolene, RandomStringGenerator využíva ThreadLocalRandom pre náhodnosť. Teraz je dôležité spomenúť že to nezabezpečuje kryptografickú bezpečnosť.

Zdroj náhodnosti však môžeme nastaviť pomocou usingRandom (TextRandomProvider). Napríklad môžeme použiť SecureTextRandomProvider pre kryptografické zabezpečenie:

public String generateRandomSpecialCharacters (int dĺžka) {SecureTextRandomProvider stp = nový SecureTextRandomProvider (); RandomStringGenerator pwdGenerator = nový RandomStringGenerator.Builder () .withinRange (33, 45). UsingRandom (stp) .build (); návrat pwdGenerator.generate (dĺžka); }

4. Používanie RandomStringUtils

Ďalšou možnosťou, ktorú by sme mohli použiť, je RandomStringUtils triedy v knižnici Apache Commons Lang. Táto trieda sprístupňuje niekoľko statických metód, ktoré môžeme použiť na vyjadrenie problému.

Pozrime sa, ako môžeme poskytnúť rozsah kódových bodov, ktoré sú prijateľné pre heslo:

 public String generateCommonLangPassword () {String upperCaseLetters = RandomStringUtils.random (2, 65, 90, true, true); Reťazec lowerCaseLetters = RandomStringUtils.random (2, 97, 122, true, true); Čísla reťazcov = RandomStringUtils.randomNumeric (2); Reťazec specialChar = RandomStringUtils.random (2, 33, 47, false, false); Reťazec totalChars = RandomStringUtils.randomAlphanumeric (2); Reťazec combineChars = upperCaseLetters.concat (lowerCaseLetters) .concat (čísla) .concat (specialChar) .concat (totalChars); Zoznam pwdChars = combinedChars.chars () .mapToObj (c -> (char) c) .collect (Collectors.toList ()); Zbierky.shuffle (pwdChars); Reťazcové heslo = pwdChars.stream () .collect (StringBuilder :: new, StringBuilder :: append, StringBuilder :: append) .toString (); návratové heslo; }

Ak chcete vygenerované heslo overiť, overme počet numerických znakov:

@Test public void whenPasswordGeneratedUsingCommonsLang3_thenSuccessful () {RandomPasswordGenerator passGen = nový RandomPasswordGenerator (); Reťazcové heslo = passGen.generateCommonsLang3Password (); int numCount = 0; pre (char c: password.toCharArray ()) 

Tu, RandomStringUtils využíva Náhodné štandardne ako zdroj náhodnosti. V knižnici však existuje metóda, ktorá nám umožňuje určiť zdroj náhodnosti:

Reťazec lowerCaseLetters = RandomStringUtils. random (2, 97, 122, true, true, null, new SecureRandom ());

Teraz by sme mohli zabezpečiť kryptografické zabezpečenie pomocou inštancie SecureRandom. Túto funkcionalitu však nemožno rozšíriť na iné metódy v knižnici. Na okraj, Apache sa zasadzuje za používanie servera RandomStringUtils iba pre jednoduché prípady použitia.

5. Používanie metódy Custom Utility

Môžeme tiež využiť SecureRandom triedy na vytvorenie vlastnej triedy nástrojov pre náš scenár. Pre začiatočníkov vygenerujme reťazec špeciálnych znakov dĺžky dva:

public Stream getRandomSpecialChars (int count) {Random random = new SecureRandom (); IntStream specialChars = random.ints (počet, 33, 45); return specialChars.mapToObj (data -> (char) data); }

Všimnite si to tiež 33 a 45 označuje rozsah znakov Unicode. Teraz môžeme podľa našich požiadaviek vygenerovať viac streamov. Potom môžeme zlúčiť výsledkové sady a vygenerovať požadované heslo:

public String generateSecureRandomPassword () {Stream pwdStream = Stream.concat (getRandomNumbers (2), Stream.concat (getRandomSpecialChars (2), Stream.concat (getRandomAlphabets (2, true), getRandomAlphabets (4, false))))); Zoznam charList = pwdStream.collect (Collectors.toList ()); Collections.shuffle (charList); Reťazcové heslo = charList.stream () .collect (StringBuilder :: new, StringBuilder :: append, StringBuilder :: append) .toString (); návratové heslo; } 

Teraz overme vygenerované heslo pre počet špeciálnych znakov:

@Test public void whenPasswordGeneratedUsingSecureRandom_thenSuccessful () {RandomPasswordGenerator passGen = nový RandomPasswordGenerator (); Reťazec heslo = passGen.generateSecureRandomPassword (); int specialCharCount = 0; pre (char c: password.toCharArray ()) c = 2); 

6. Záver

V tomto tutoriáli sme boli schopní generovať heslá zodpovedajúce našim požiadavkám pomocou rôznych knižníc.

Ako vždy, ukážky kódu použité v článku sú k dispozícii na GitHub.

Java dole

Práve som oznámil nové Naučte sa jar kurz zameraný na základy jari 5 a Spring Boot 2:

>> SKONTROLUJTE KURZ

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