Generer et sikkert tilfeldig 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. Introduksjon

I denne opplæringen vil vi se på forskjellige metoder vi kan bruke til å generere et sikkert tilfeldig passord i Java.

I eksemplene våre genererer vi passord med ti tegn, hver med minst to små bokstaver, to store bokstaver, to sifre og to spesialtegn.

2. Bruke Passay

Passay er et passordhåndhevelsesbibliotek. Spesielt kan vi bruke biblioteket til å generere passordet ved hjelp av et konfigurerbart regelsett.

Ved hjelp av standard CharacterData implementeringer, kan vi formulere reglene som kreves for passordet. Videre kan vi formulere skikk CharacterData implementeringer som passer våre krav:

offentlig streng genererePassayPassword () {PasswordGenerator gen = ny PasswordGenerator (); CharacterData lowerCaseChars = EnglishCharacterData.LowerCase; CharacterRule lowerCaseRule = ny CharacterRule (lowerCaseChars); lowerCaseRule.setNumberOfCharacters (2); CharacterData upperCaseChars = EnglishCharacterData.UpperCase; CharacterRule upperCaseRule = ny CharacterRule (upperCaseChars); upperCaseRule.setNumberOfCharacters (2); CharacterData digitChars = EnglishCharacterData.Digit; CharacterRule digitRule = ny CharacterRule (digitChars); digitRule.setNumberOfCharacters (2); CharacterData specialChars = new CharacterData () {public String getErrorCode () {return ERROR_CODE; } offentlige String getCharacters () {return "[email protected] # $% ^ & * () _ +"; }}; CharacterRule splCharRule = ny CharacterRule (specialChars); splCharRule.setNumberOfCharacters (2); Strengpassord = gener.generatePassword (10, splCharRule, lowerCaseRule, upperCaseRule, digitRule); returpassord; }

Her har vi laget en tilpasset CharacterData implementering for spesialtegn. Dette tillater oss å begrense settet med gyldige tegn.

Bortsett fra det, bruker vi standardimplementeringer av CharacterData for våre andre regler.

La oss nå sjekke generatoren vår mot en enhetstest. For eksempel kan vi sjekke tilstedeværelsen av to spesialtegn:

@Test offentlig ugyldig nårPasswordGeneratedUsingPassay_thenSuccessful () {RandomPasswordGenerator passGen = new RandomPasswordGenerator (); Strengpassord = passGen.generatePassayPassword (); int specialCharCount = 0; for (char c: password.toCharArray ()) hvis (c> = 33 

Det er verdt å merke seg det Selv om Passay er åpen kildekode, har den to lisenser under både LGPL og Apache 2. Som med annen tredjepartsprogramvare, må vi være sikker på å overholde disse lisensene når vi bruker den i våre produkter. GNU-nettstedet har mer informasjon om LGPL og Java.

3. Bruke RandomStringGenerator

La oss se på RandomStringGenerator i Apache Commons Text. Med RandomStringGenerator, vi kan generere Unicode-strenger som inneholder det spesifiserte antall kodepunkter.

Nå oppretter vi en forekomst av generatoren ved hjelp av RandomStringGenerator.Builder klasse. Selvfølgelig kan vi også manipulere egenskapene til generatoren ytterligere.

Ved hjelp av byggherren kan vi enkelt endre standardimplementeringen av tilfeldighet. Videre kan vi også definere tegnene som er tillatt i strengen:

public String generateRandomSpecialCharacters (int length) {RandomStringGenerator pwdGenerator = new RandomStringGenerator.Builder (). withinRange (33, 45) .build (); returner pwdGenerator.generate (lengde); } 

Nå, en begrensning for bruk RandomStringGenerator er det det mangler muligheten til å spesifisere antall tegn i hvert sett, som i Passay. Vi kan imidlertid omgå det ved å slå sammen resultatene fra flere sett:

offentlig streng generereCommonTextPassword () {String pwString = createRandomSpecialCharacters (2) .concat (generateRandomNumbers (2)) .concat (createRandomAlphabet (2, true)) .concat (createRandomAlphabet (2, false)) .concat (generere 2 Liste pwChars = pwString.chars () .mapToObj (data -> (char) data) .collect (Collectors.toList ()); Collections.shuffle (pwChars); Strengpassord = pwChars.stream () .collect (StringBuilder :: new, StringBuilder :: append, StringBuilder :: append) .toString (); returpassord; }

La oss deretter validere det genererte passordet ved å bekrefte små bokstaver:

@Test offentlig ugyldig nårPasswordGeneratedUsingCommonsText_thenSuccessful () {RandomPasswordGenerator passGen = new RandomPasswordGenerator (); Strengpassord = passGen.generateCommonTextPassword (); int lowerCaseCount = 0; for (char c: password.toCharArray ()) 

Som standard, RandomStringGenerator bruker ThreadLocalRandom for tilfeldighet. Nå er det viktig å nevne at dette ikke sikrer kryptografisk sikkerhet.

Vi kan imidlertid stille kilden til tilfeldighet ved hjelp av usingRandom (TextRandomProvider). For eksempel kan vi gjøre bruk av SecureTextRandomProvider for kryptografisk sikkerhet:

offentlig streng generere RandomSpecialCharacters (int lengde) {SecureTextRandomProvider stp = ny SecureTextRandomProvider (); RandomStringGenerator pwdGenerator = ny RandomStringGenerator.Builder () .withinRange (33, 45) .usingRandom (stp) .build (); returner pwdGenerator.generate (lengde); }

4. Bruke RandomStringUtils

Et annet alternativ som vi kan benytte er RandomStringUtils klasse i Apache Commons Lang-biblioteket. Denne klassen avslører flere statiske metoder som vi kan bruke til vår problemstilling.

La oss se hvordan vi kan gi rekkevidden av kodepunkter som er akseptable for passordet:

 public String generateCommonLangPassword () {String upperCaseLetters = RandomStringUtils.random (2, 65, 90, true, true); String lowerCaseLetters = RandomStringUtils.random (2, 97, 122, true, true); Strengnumre = RandomStringUtils.randomNumeric (2); String specialChar = RandomStringUtils.random (2, 33, 47, false, false); String totalChars = RandomStringUtils.randomAlphanumeric (2); String combinedChars = upperCaseLetters.concat (lowerCaseLetters) .concat (tall) .concat (specialChar) .concat (totalChars); Liste pwdChars = combinedChars.chars () .mapToObj (c -> (char) c) .collect (Collectors.toList ()); Collections.shuffle (pwdChars); Strengpassord = pwdChars.stream () .collect (StringBuilder :: new, StringBuilder :: append, StringBuilder :: append) .toString (); returpassord; }

For å validere det genererte passordet, la oss bekrefte antall numeriske tegn:

@Test offentlig ugyldig nårPasswordGeneratedUsingCommonsLang3_thenSuccessful () {RandomPasswordGenerator passGen = new RandomPasswordGenerator (); Strengpassord = passGen.generateCommonsLang3Password (); int numCount = 0; for (char c: password.toCharArray ()) 

Her, RandomStringUtils bruker Tilfeldig som standard som kilde til tilfeldighet. Imidlertid er det en metode i biblioteket som lar oss spesifisere kilden til tilfeldighet:

String lowerCaseLetters = RandomStringUtils. tilfeldig (2, 97, 122, sann, sann, null, ny SecureRandom ());

Nå kan vi sikre kryptografisk sikkerhet ved hjelp av en forekomst av SecureRandom. Denne funksjonaliteten kan imidlertid ikke utvides til andre metoder i biblioteket. På en sidemerknad, Apache går inn for bruk av RandomStringUtils kun for enkel brukstilfeller.

5. Bruke en tilpasset verktøymetode

Vi kan også benytte oss av SecureRandom klasse for å lage en tilpasset verktøyklasse for vårt scenario. For det første, la oss generere en streng med spesielle tegn i lengde to:

public Stream getRandomSpecialChars (int count) {Tilfeldig tilfeldig = ny SecureRandom (); IntStream specialChars = random.ints (count, 33, 45); returner specialChars.mapToObj (data -> (char) data); }

Legg også merke til det 33 og 45 betegne rekkevidden av Unicode-tegn. Nå kan vi generere flere strømmer i henhold til våre krav. Da kan vi slå sammen resultatsettene for å generere det nødvendige passordet:

offentlig streng generereSecureRandomPassword () {Stream pwdStream = Stream.concat (getRandomNumbers (2), Stream.concat (getRandomSpecialChars (2), Stream.concat (getRandomAlphabets (2, true), getRandomAlphabets (4, false)))); Liste charList = pwdStream.collect (Collectors.toList ()); Collections.shuffle (charList); Strengpassord = charList.stream () .collect (StringBuilder :: new, StringBuilder :: append, StringBuilder :: append) .toString (); returpassord; } 

La oss nå validere det genererte passordet for antall spesialtegn:

@Test offentlig ugyldig nårPasswordGeneratedUsingSecureRandom_thenSuccessful () {RandomPasswordGenerator passGen = new RandomPasswordGenerator (); Strengpassord = passGen.generateSecureRandomPassword (); int specialCharCount = 0; for (char c: password.toCharArray ()) c = 2); 

6. Konklusjon

I denne opplæringen var vi i stand til å generere passord, i samsvar med våre krav, ved hjelp av forskjellige biblioteker.

Som alltid er kodeeksemplene som brukes i artikkelen 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