×

Search anything:

Password generator, strength checker and password crack time estimator in Java

Binary Tree book by OpenGenus

Open-Source Internship opportunity by OpenGenus for programmers. Apply now.

In this article, we will discuss several ways to code a program that generates random password, And another program that checks the strength of user's input password in Java, And final program that estimates the time needed to crack a user's password.

Pre-requisites:

Table of contents:

  • Using Java's Random class
  • Using Apache Commons Lang library
  • Creating a password strength checker

Using Java's Random class

One way to create a password generator in Java is to use Java's built-in Random class to generate random characters. Here's an example code:

  • The code defines a static method named generatePassword that takes an integer argument "size" which specifies the length of the password to be generated.

  • The method generates a random password consisting of alphanumeric characters and special symbols by creating a string of characters that it will choose from. It then initializes a Random class to generate random indices to select characters from the string, and concatenates these randomly chosen characters to form the password.

  • The code then calls the generatePassword method from the main method, takes user input for the desired password length, and outputs the generated password to the console using the System.out.println method.

package myjavaapplication;
import java.util.Random;
import java.util.Scanner;
public class MyJavaApplication {
    static String generatePassword(int size)
    {
    // Setting the characters to output password from it
        String alphanum = "0123456789!@#$%^&*abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String result = "";
        // initializing a new Random class
        Random random = new Random();
        for (int i = 0; i < size; i++)
        {
            // Choosing a random index from alphanum
            int index = random.nextInt(alphanum.length());
            // Adding the char from index
            result += alphanum.charAt(index);
        }
        return result;
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int userInput = in.nextInt();
        System.out.println(generatePassword(userInput));
    }
    
}

Input:

12

Output:

S%VmJWV0ev60

Using Apache Commons Lang library

Another way to generate a password in Java is to use the Apache Commons Lang library. The library includes a RandomStringUtils class that provides various methods for generating random strings. Here's an example code:

  • The code imports the RandomStringUtils class from the Apache Commons Lang library to generate a random password of a specified length.

  • The code defines a static method named generatePassword that takes an integer argument "size" which specifies the length of the password to be generated. The method uses the RandomStringUtils.random method to generate a password consisting of alphanumeric characters and returns it as a string.

  • The code then calls the generatePassword method from the main method, takes user input for the desired password length, and outputs the generated password to the console using the System.out.println method.

package myjavaapplication;
import org.apache.commons.lang3.RandomStringUtils; // Import the RandomStringUtils
import java.util.Scanner;
public class MyJavaApplication {
    static String generatePassword(int size)
    {
        String password = RandomStringUtils.random(size, true, true); // Generate a random password of length size
        System.out.println("Generated Password: " + password);
        return password;
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int userInput = in.nextInt();
        System.out.println(generatePassword(userInput));
    }
    
}

Input:

8

Output:

dLj7E3Zt

Creating a password strength checker

To create a password strength checker, you can evaluate the strength of a password based on various criteria, such as length, complexity, and use of special characters. Here's an example code:

  • The code takes user input for a password and then performs several checks on the password to determine its strength, such as checking if it contains at least one uppercase letter, lowercase letter, number, and special symbol.

  • Based on the number of checks passed, the code assigns a strength level to the password and returns a message to the user indicating the strength level. The possible strength levels are weak, good, strong, and stronger than Fort Knox.

  • The code uses a static method named generatePassword to perform the password checks and return the strength level message. It then calls this method from the main method, which takes user input and outputs the generated message to the console.

package myjavaapplication;
import java.util.Scanner;
public class JavaApplication {
  static String generatePassword(String password) {
    int length = password.length();
    // Check if the password contains at least one uppercase letter
    boolean hasUppercase = !password.equals(password.toLowerCase());
    // Check if the password contains at least one lowercase letter
    boolean hasLowercase = !password.equals(password.toUpperCase());
    // Check if the password contains at least one number
    boolean hasNumbers = password.matches(".*\\d.*");
    // Check if the password contains at least one special symbol
    boolean hasSymbols = password.matches(".*[!@#$%^&*_=+-/.?<>)].*");

    int strength = 0;

    if (length >= 8) {
        strength++;
    }

    if (hasUppercase && hasLowercase) {
        strength++;
    }

    if (hasNumbers) {
        strength++;
    }

    if (hasSymbols) {
        strength++;
    }
    if (strength == 1)
    {
        return "Your password is weak";
    }
    else if (strength == 2){
        return "Your password is good";
    }
    else if (strength == 3){
        return "Your password is strong";
    }
    else if (strength == 4){
        return "Your password is stronger than fort knox!!!";
    }
    return "Your password is bad";
  }
  public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String userInput = in.nextLine();
        System.out.println(generatePassword(userInput));
    }
}

Input:

Mypassword1234

Output:

Your password is strong

This code checks the strength of a given password based on the length, use of uppercase and lowercase letters, numbers, and symbols. The strength is evaluated on a scale of 1 to 4, with 4 being the strongest.

Time to crack password estimator

  • Calculate the number of operations needed to predict the password. This may include checking the position of the password in the list of generated password (lexicographic rank) and consider it takes M operations to compare a string of length M.
  • Assume a computer can do 10^7 operations per second.
  • If the password is in the list of common passwords, time can be assumed at 0.1 second.
package myjavaapplication; // Defines a package that contains the class

import java.io.BufferedReader; // Imports the BufferedReader class from the java.io package
import java.io.FileReader; // Imports the FileReader class from the java.io package
import java.io.IOException; // Imports the IOException class from the java.io package
import java.math.BigInteger; // Imports the BigInteger class from the java.math package
import java.util.Scanner; // Imports the Scanner class from the java.util

public class MyJavaApplication { // Defines a public class called MyJavaApplication
    private static final int OPERATIONS_PER_SECOND = 10000000; // Defines a constant integer called OPERATIONS_PER_SECOND and sets it to 10000000
    private static final double TIME_FOR_COMMON_PASSWORD = 0.1; // Defines a constant double called TIME_FOR_COMMON_PASSWORD and sets it to 0.1

    public static void main(String[] args) throws IOException { // Defines a public static void method called main that takes a String array called args as a parameter and throws an IOException
        Scanner in = new Scanner(System.in);
        String password = in.nextLine(); // Declares and initializes a String variable called password with the value "123456789"

        String commonPasswordsFilePath = "C:\\common-passwords.txt"; // Declares and initializes a String variable called commonPasswordsFilePath with the value "C:\\common-passwords.txt"

        boolean isPasswordCommon = false; // Declares and initializes a boolean variable called isPasswordCommon with the value false

        // Check if password is in common-passwords file
        try (BufferedReader br = new BufferedReader(new FileReader(commonPasswordsFilePath))) { // Defines a try block that creates a new BufferedReader and a new FileReader object to read the file at commonPasswordsFilePath
            String line; // Declares a String variable called line
            while ((line = br.readLine()) != null) { // Defines a while loop that reads each line of the file until the end of the file is reached
                if (line.equals(password)) { // Defines an if statement that checks if the current line is equal to the password variable
                    isPasswordCommon = true; // Sets the isPasswordCommon variable to true if the password is found in the file
                    break; // Exits the loop
                }
            }
        }

        BigInteger rank = getLexicographicRank(password); // Declares a BigInteger variable called rank and initializes it to the value returned by the getLexicographicRank method with the password variable as a parameter

        double timeInSeconds = isPasswordCommon ? TIME_FOR_COMMON_PASSWORD : getTimeToCrack(rank, password.length()); // Declares a double variable called timeInSeconds and initializes it to the value returned by either the TIME_FOR_COMMON_PASSWORD constant or the getTimeToCrack method, depending on whether the password is common or not

        printTime(timeInSeconds); // Calls the printTime method with the timeInSeconds variable as a parameter
    }

    private static BigInteger getLexicographicRank(String password) {
    BigInteger rank = BigInteger.ZERO; // Initialize rank to zero

    char[] passwordArray = password.toCharArray(); // Convert password to a character array
    int length = passwordArray.length; // Get length of the password
    int[] characterCount = new int[256]; // Initialize an array to count the frequency of characters

    // Count frequency of characters
    for (char c : passwordArray) {
        characterCount[c]++; // Increment the count for the character
    }

    // Calculate the rank
    for (int i = 0; i < length; i++) {
        // Count the number of characters smaller than password[i] that can be placed at position i
        int smallerCharCount = 0;
        for (int j = 0; j < passwordArray[i]; j++) {
            if (characterCount[j] > 0) {
                smallerCharCount++; // Increment count if character can be used
            }
        }

        // Update the rank
        rank = rank.add(BigInteger.valueOf(smallerCharCount)
                .multiply(factorial(length - i - 1))); //updates the value of a BigInteger variable named "rank" by adding the result of multiplying BigInteger.valueOf(smallerCharCount) and the factorial of (length - i - 1) to its current value.

        // Decrement the count of the character used
        characterCount[passwordArray[i]]--;
    }

    return rank; // Return the final rank
}

    // Method to calculate the factorial of a number
    private static BigInteger factorial(int n) {
        BigInteger fact = BigInteger.ONE;
        // Calculate factorial using a loop
        for (int i = 2; i <= n; i++) {
            fact = fact.multiply(BigInteger.valueOf(i)); //updates the value of a BigInteger variable named "fact" by multiplying its current value with BigInteger.valueOf(i).
        }

        return fact;
    }
    // Method to calculate the time to crack a password using its lexicographic rank
    private static double getTimeToCrack(BigInteger rank, int passwordLength) {
        // Initialize sum to 0
        BigInteger sum = BigInteger.ZERO;
        // Calculate sum of products of length i and number of possible characters (72)
        for (int i = 1; i < passwordLength; i++) {
            BigInteger product = BigInteger.valueOf(i).multiply(BigInteger.valueOf(72).pow(i)); //This line of code initializes a BigInteger variable named "product" with the result of multiplying BigInteger.valueOf(i) by BigInteger.valueOf(72) raised to the power of i
            sum = sum.add(product);
        }
        // Add the product of password length and lexicographic rank to the sum
        BigInteger total = sum.add(BigInteger.valueOf(passwordLength).multiply(rank));
        // Calculate the time required to crack the password
        double timeInSeconds = total.divide(BigInteger.valueOf(OPERATIONS_PER_SECOND)).doubleValue();
        
        return timeInSeconds;
    }
    // Method to return time in minutes, hours, days, weeks, months, years or centuries
    private static void printTime(double timeInSeconds) {
    final double SECONDS_PER_MINUTE = 60;
    final double MINUTES_PER_HOUR = 60;
    final double HOURS_PER_DAY = 24;
    final double DAYS_PER_WEEK = 7;
    final double DAYS_PER_MONTH = 30.44;
    final double MONTHS_PER_YEAR = 12;
    final double YEARS_PER_CENTURY = 100;
    
    if (timeInSeconds < SECONDS_PER_MINUTE) {
        System.out.printf("Predicted time to crack password: %.2f seconds", timeInSeconds);
    } else if (timeInSeconds < SECONDS_PER_MINUTE * MINUTES_PER_HOUR) {
        double minutes = timeInSeconds / SECONDS_PER_MINUTE;
        System.out.printf("Predicted time to crack password: %.2f minutes", minutes);
    } else if (timeInSeconds < SECONDS_PER_MINUTE * MINUTES_PER_HOUR * HOURS_PER_DAY) {
        double hours = timeInSeconds / (SECONDS_PER_MINUTE * MINUTES_PER_HOUR);
        System.out.printf("Predicted time to crack password: %.2f hours", hours);
    } else if (timeInSeconds < SECONDS_PER_MINUTE * MINUTES_PER_HOUR * HOURS_PER_DAY * DAYS_PER_WEEK) {
        double days = timeInSeconds / (SECONDS_PER_MINUTE * MINUTES_PER_HOUR * HOURS_PER_DAY);
        System.out.printf("Predicted time to crack password: %.2f days", days);
    } else if (timeInSeconds < SECONDS_PER_MINUTE * MINUTES_PER_HOUR * HOURS_PER_DAY * DAYS_PER_MONTH * MONTHS_PER_YEAR) {
        double weeks = timeInSeconds / (SECONDS_PER_MINUTE * MINUTES_PER_HOUR * HOURS_PER_DAY * DAYS_PER_WEEK);
        System.out.printf("Predicted time to crack password: %.2f weeks", weeks);
    } else if (timeInSeconds < SECONDS_PER_MINUTE * MINUTES_PER_HOUR * HOURS_PER_DAY * DAYS_PER_MONTH * MONTHS_PER_YEAR * YEARS_PER_CENTURY) {
        double months = timeInSeconds / (SECONDS_PER_MINUTE * MINUTES_PER_HOUR * HOURS_PER_DAY * DAYS_PER_MONTH);
        System.out.printf("Predicted time to crack password: %.2f months", months);
    } else {
        double centuries = timeInSeconds / (SECONDS_PER_MINUTE * MINUTES_PER_HOUR * HOURS_PER_DAY * DAYS_PER_MONTH * MONTHS_PER_YEAR * YEARS_PER_CENTURY);
        System.out.printf("Predicted time to crack password: %.2f centuries", centuries);
    }
  }
}

Easy password input:

123456789

Output:

Predicted time to crack password: 0.10 seconds

Hard password input:

ImAVeryStrongPassword82374#%

Output:

Predicted time to crack password: 121912733983964670000000000000000000.00 centuries

With this article at OpenGenus, you must have the complete idea of how to create a program that generates random passwords and how to create a program that tells the strength of a password in Java.

Password generator, strength checker and password crack time estimator in Java
Share this