Generer et sikkert tilfeldig passord i Java
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 KURSET1. 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: 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: 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. 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: 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: La oss deretter validere det genererte passordet ved å bekrefte små bokstaver: 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: 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: For å validere det genererte passordet, la oss bekrefte antall numeriske tegn: Her, RandomStringUtils bruker Tilfeldig som standard som kilde til tilfeldighet. Imidlertid er det en metode i biblioteket som lar oss spesifisere kilden til tilfeldighet: 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. 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: 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: La oss nå validere det genererte passordet for antall spesialtegn: 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.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; }
@Test offentlig ugyldig nårPasswordGeneratedUsingPassay_thenSuccessful () {RandomPasswordGenerator passGen = new RandomPasswordGenerator (); Strengpassord = passGen.generatePassayPassword (); int specialCharCount = 0; for (char c: password.toCharArray ()) hvis (c> = 33
3. Bruke RandomStringGenerator
public String generateRandomSpecialCharacters (int length) {RandomStringGenerator pwdGenerator = new RandomStringGenerator.Builder (). withinRange (33, 45) .build (); returner pwdGenerator.generate (lengde); }
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; }
@Test offentlig ugyldig nårPasswordGeneratedUsingCommonsText_thenSuccessful () {RandomPasswordGenerator passGen = new RandomPasswordGenerator (); Strengpassord = passGen.generateCommonTextPassword (); int lowerCaseCount = 0; for (char c: password.toCharArray ())
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
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; }
@Test offentlig ugyldig nårPasswordGeneratedUsingCommonsLang3_thenSuccessful () {RandomPasswordGenerator passGen = new RandomPasswordGenerator (); Strengpassord = passGen.generateCommonsLang3Password (); int numCount = 0; for (char c: password.toCharArray ())
String lowerCaseLetters = RandomStringUtils. tilfeldig (2, 97, 122, sann, sann, null, ny SecureRandom ());
5. Bruke en tilpasset verktøymetode
public Stream getRandomSpecialChars (int count) {Tilfeldig tilfeldig = ny SecureRandom (); IntStream specialChars = random.ints (count, 33, 45); returner specialChars.mapToObj (data -> (char) data); }
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; }
@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
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