mardi 3 novembre 2015

generating random password with lot of restriction in java

I would like to create a password generator that create password according to the restriction set by user. The restrictions is:

  1. Minimum Password Length
  2. Maximum Password Length
  3. Minimum Letter And Digit
  4. Minimum Letter
  5. Minimum Uppercase Letter
  6. Minimum Lowercase Letter
  7. Minimum Digit
  8. Maximum Repeat Character

I lookout through google and most of the example code doesn't meet the requirement that I need. So I improvise the code like this:

private char[] GeneratePassword(int minLength, int maxLength,
        int maxRepeatCharacter, int minLetterAndDigit, int minLetter,
        int minLowerCaseLetter, int minUpperCaseLetter, int minDigit) {

    final String LETTER = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    final String UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    final String LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
    final String DIGIT = "0123456789";
    final String[] randomSelector = {LETTER,UPPERCASE,LOWERCASE,DIGIT};

    int len = getRandomNumber(minLength, maxLength);
    char[] passwordGenerated = new char[len];
    char[] characterUsed = new char[len];
    int selection;
    int letterAndDigitUsed = 0;
    int letterUsed = 0;
    int lowerCaseLetterUsed = 0;
    int upperCaseLetterUsed = 0;
    int digitUsed = 0;
    int index = 0;

    if (minLength > maxLength) {
      // throw new IllegalArgumentException("Min.Length > Max.Length!");
    }

    if (minLetter + minDigit > minLetterAndDigit) {
      // throw new IllegalArgumentException("Error!");
    }

    while (index != len) {
        selection = getRandomNumber(0, randomSelector.length);
        if (selection == 0) {
            passwordGenerated[index] = LETTER.charAt(RandomUtils.nextInt(0,
                    LETTER.length()));
            if (checkRepeatCharacter(passwordGenerated[index],
                    characterUsed, index, maxRepeatCharacter) == false) {
                characterUsed[index] = passwordGenerated[index];
                index++;
                letterUsed++;
                letterAndDigitUsed++;
                break;
            }
        } else if (selection == 1) {
            passwordGenerated[index] = UPPERCASE.charAt(RandomUtils
                    .nextInt(0, UPPERCASE.length()));
            if (checkRepeatCharacter(passwordGenerated[index],
                    characterUsed, index, maxRepeatCharacter) == false) {
                characterUsed[index] = passwordGenerated[index];
                index++;
                upperCaseLetterUsed++;
                letterAndDigitUsed++;
                break;
            }
        } else if (selection == 2) {
            passwordGenerated[index] = LOWERCASE.charAt(RandomUtils
                    .nextInt(0, LOWERCASE.length()));
            if (checkRepeatCharacter(passwordGenerated[index],
                    characterUsed, index, maxRepeatCharacter) == false) {
                characterUsed[index] = passwordGenerated[index];
                index++;
                lowerCaseLetterUsed++;
                letterAndDigitUsed++;
                break;
            }
        } else if (selection == 3) {
            passwordGenerated[index] = DIGIT.charAt(RandomUtils.nextInt(0,
                    DIGIT.length()));
            if (checkRepeatCharacter(passwordGenerated[index],
                    characterUsed, index, maxRepeatCharacter) == false) {
                characterUsed[index] = passwordGenerated[index];
                index++;
                digitUsed++;
                letterAndDigitUsed++;
                break;
            }
        }
    }

    return passwordGenerated;
}

private boolean checkRepeatCharacter(char passwordGenerated,
        char[] passwordUsed, int index, int maxRepeatCharacter) {
    int characterRepeated = 0;
    for (int i = 0; i < index; i++) {
        if (String.valueOf(passwordUsed[i]).equals(
                String.valueOf(passwordGenerated))) {
            characterRepeated++;
            if (characterRepeated == maxRepeatCharacter) {
                return true;
            }
        }
    }
    return false;
}

private int getRandomNumber(int minLength, int maxLength) {
    Random r = new Random();
    return r.nextInt(maxLength - minLength) + minLength;
}

The problem that I'm having is how to ensure the minimum condition are met. At the same time, I dont want my password to be generated by repeating at the same type of character.

  1. Example: If I put my maximum password length to 10 and I want a minimum digit of 5. I prefer to have 1jP2k3o4m9 rather than 57812aJ9tP.

  2. 2nd Example: If I put my maximum password length to 5 and I want a minimum lowercase letter of 3. I prefer to have Pj9mn rather than jkl5V.

As you can see, the 2nd generated password is trying to fullfill the minimum requirement first, then only do a random selection to other character type. Which will make the password more vulnerable. Is there any way to do this algorithm.

Ref: Generating a Random Password with Restrictions in Java




Aucun commentaire:

Enregistrer un commentaire