Main Tutorials

Java password generator example

Here’s the Java password generator to generate a secure password that consists of two lowercase chars, two uppercase chars, two digits, two special chars, and pad the rest with random chars until it reaches the length of 20 characters.

Secure password requirements:

  1. Password must contain at least two digits [0-9].
  2. Password must contain at least two lowercase Latin characters [a-z].
  3. Password must contain at least two uppercase Latin characters [A-Z].
  4. Password must contain at least two special characters like ! @ # & ( ) etc.
  5. Password has a length of 20 characters.

1. Java Secure Password Generator

Below are the steps to generate a secure password:

  1. Defined all the supported characters.
  2. Get random two characters from a list of lowercase characters [a-z].
  3. Get random two characters from a list of uppercase characters [A-Z].
  4. Get random two characters from a list of digits [0-9].
  5. Get random two characters from a list of special characters [!@#&...].
  6. Get another random 12 characters from a list of supported characters (lowercase, uppercase, digit, and special characters).
  7. Combine all the above 20 random characters.
  8. Shuffle the result in step 7 to produce a random order.
  9. This is the final secure password.
PasswordGenerator.java

package com.mkyong.regex.password;

import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class PasswordGenerator {

    private static final String CHAR_LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
    private static final String CHAR_UPPERCASE = CHAR_LOWERCASE.toUpperCase();
    private static final String DIGIT = "0123456789";
    private static final String OTHER_PUNCTUATION = "!@#&()–[{}]:;',?/*";
    private static final String OTHER_SYMBOL = "~$^+=<>";
    private static final String OTHER_SPECIAL = OTHER_PUNCTUATION + OTHER_SYMBOL;
    private static final int PASSWORD_LENGTH = 20;

    private static final String PASSWORD_ALLOW =
            CHAR_LOWERCASE + CHAR_UPPERCASE + DIGIT + OTHER_SPECIAL;

    private static SecureRandom random = new SecureRandom();

    public static void main(String[] args) {
        generateStrongPassword();
    }

    public static String generateStrongPassword() {

        StringBuilder result = new StringBuilder(PASSWORD_LENGTH);

        // at least 2 chars (lowercase)
        String strLowerCase = generateRandomString(CHAR_LOWERCASE, 2);
        System.out.format("%-20s: %s%n", "Chars (Lowercase)", strLowerCase);
        result.append(strLowerCase);

        // at least 2 chars (uppercase)
        String strUppercaseCase = generateRandomString(CHAR_UPPERCASE, 2);
        System.out.format("%-20s: %s%n", "Chars (Uppercase)", strUppercaseCase);
        result.append(strUppercaseCase);

        // at least 2 digits
        String strDigit = generateRandomString(DIGIT, 2);
        System.out.format("%-20s: %s%n", "Digits", strDigit);
        result.append(strDigit);

        // at least 2 special characters (punctuation + symbols)
        String strSpecialChar = generateRandomString(OTHER_SPECIAL, 2);
        System.out.format("%-20s: %s%n", "Special chars", strSpecialChar);
        result.append(strSpecialChar);

        // remaining, just random
        String strOther = generateRandomString(PASSWORD_ALLOW, PASSWORD_LENGTH - 8);
        System.out.format("%-20s: %s%n", "Others", strOther);
        result.append(strOther);

        String password = result.toString();
        // combine all
        System.out.format("%-20s: %s%n", "Password", password);
        // shuffle again
        System.out.format("%-20s: %s%n", "Final Password", shuffleString(password));
        System.out.format("%-20s: %s%n%n", "Password Length", password.length());

        return password;
    }

    // generate a random char[], based on `input`
    private static String generateRandomString(String input, int size) {

        if (input == null || input.length() <= 0)
            throw new IllegalArgumentException("Invalid input.");
        if (size < 1) throw new IllegalArgumentException("Invalid size.");

        StringBuilder result = new StringBuilder(size);
        for (int i = 0; i < size; i++) {
            // produce a random order
            int index = random.nextInt(input.length());
            result.append(input.charAt(index));
        }
        return result.toString();
    }

    // for final password, make it more random
    public static String shuffleString(String input) {
        List<String> result = Arrays.asList(input.split(""));
        Collections.shuffle(result);
        // java 8
        return result.stream().collect(Collectors.joining());
    }

}

Output

Terminal

  Chars (Lowercase)   : ob
  Chars (Uppercase)   : AB
  Digits              : 67
  Special chars       : <@
  Others              : IR{3Nl@@^+xE
  Password            : obAB67<@IR{3Nl@@^+xE
  Final Password      : AN@@b6RBxlI3o+^E{@7<
  Password Length     : 20

2. Run Password Generator five times.

Run five times, and see the random secure passwords.


  public static void main(String[] args) {
      for (int i = 0; i < 5; i++) {
          generateStrongPassword();
      }
  }

Output


Chars (Lowercase)   : fs
Chars (Uppercase)   : AD
Digits              : 45
Special chars       : [–
Others              : UOJ:1?pn$CA{
Password            : fsAD45[–UOJ:1?pn$CA{
Final Password      : CAU5{f:pJ$[1Dns?AO4–
Password Length     : 20

Chars (Lowercase)   : cl
Chars (Uppercase)   : LL
Digits              : 32
Special chars       : :]
Others              : ${CS2R]k/J$#
Password            : clLL32:]${CS2R]k/J$#
Final Password      : 3]C:Jl{k2$2#S/]c$LLR
Password Length     : 20

Chars (Lowercase)   : ae
Chars (Uppercase)   : DZ
Digits              : 90
Special chars       : ~^
Others              : 6+nLyZgiY:E/
Password            : aeDZ90~^6+nLyZgiY:E/
Final Password      : ~EY+ZgaL/e0n9i6:^ZDy
Password Length     : 20

Chars (Lowercase)   : xg
Chars (Uppercase)   : LW
Digits              : 60
Special chars       : )>
Others              : PNCo7rT,StSp
Password            : xgLW60)>PNCo7rT,StSp
Final Password      : rxoSL>WN)7Sp0CPtT6,g
Password Length     : 20

Chars (Lowercase)   : eo
Chars (Uppercase)   : OJ
Digits              : 31
Special chars       : ](
Others              : Px4C'U{(G~$D
Password            : eoOJ31](Px4C'U{(G~$D
Final Password      : 34O(G{J~'x$DUPo(]Ce1
Password Length     : 20

Password Validator
Try this regex to validate the secure password.

Password Hashing
Do not store the password as plaintext. It is a good practice to use slow hash like Argon2 to hash the password.

Download Source Code

$ git clone https://github.com/mkyong/core-java

$ cd java-regex/password

References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
3 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
mdi
4 years ago

You don’t deterministically generate a strong PW, but just a random one. In your example, in fact, you don’t always get special chars in the final PW. That’s even more evident if you want a 8-chars long PW only. When I implemented a PW generator, for example of 8-chars, i generated 4 random chars (max length – 4, as i have 4 conditions to check later): then i start verify and the single 4 conditions: lc letter, up letter, digit and special char. For each condition i verify if a suitable char is already available in the PW. If not i generate a random one from the corresponding charset only. For example if the initial PW is sh3b, i dont need to generate any lc char. So i move on and check for uc char: there is none, so I take a random uc letter from the uc letters variable. At the end i pad the rest of the string with random chars until the length is 8.

che
3 years ago
Reply to  mkyong

Thank you for the example! But i’d like to point out – in your code is an en dash which is not a standard ASCII character and may cause some code to break. I would replace it with a hyphen though!