SecureRandom class in Java provides a cryptographically secure pseudo – random number generator and its intended use is for security sensitive applications. In this example, we will not use it for its intended purpose, but rather present its methods in a simple password generator.

1.Password Generator Using Secure Random

A convention, we made for our password generator is that the final password can consist of capital letters A-Z, lower-case a-z, numbers 0-9 and the symbols #, $, %, & and @.

PasswordGenerator.java

package com.mkyong.passwordgen;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;

public class PasswordGenerator {

    private SecureRandom srand;
    private ArrayList validch;

    public PasswordGenerator() throws NoSuchAlgorithmException, NoSuchProviderException {
        srand = new SecureRandom();
        validch = new ArrayList<>();

        //Filling the ArrayList with the characters we want to use based on ascii table:
        // https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html
        for (int i = 65; i < 91; i++) {
            validch.add((char) i);// A-Z
            validch.add((char) (i + 32));// a-z
        }
        for (int i = 48; i < 58; i++) {
            validch.add((char) i);
        }
        for (int i = 35; i < 39; i++) {
            validch.add((char) i);
        }
        validch.add((char) 64);
        Collections.shuffle(validch);
    }

    public char randChar() {
        return (char) this.validch.get(srand.nextInt(this.validch.size()));
    }

    public static void main(String[] args) throws NoSuchAlgorithmException, 
        NoSuchProviderException, UnsupportedEncodingException {

        PasswordGenerator pg = new PasswordGenerator();

        StringBuilder sb = new StringBuilder();
        for (int j = 0; j < 10; j++) { // Generate 10 passwords
            for (int i = 0; i < 10; i++) { // Passwords are 10 characters long
                sb.append(pg.randChar());
            }
            System.out.println(sb.toString());
            sb.setLength(0);
        }

    }

}

Output:


s96g9RH%BH
%Cs5DjHgRD
xGea5Kb&5b
QomXOfC98s
BU0s%gqK6J
0yOkL%SHrT
j@drmKSwhy
aKwriP#xd9
XxdjIT7jr@
Qd7OE1RYNi

In the example above, we called SecureRandom with the default constructor. Instead, we could have initiated the SecureRandom using an algorithm and a provider. Depending on our application needs, we might have to specify a provider, but in general it is good to refrain from it and allow the system to use the algorithm with the highest priority.

2. Setting the seed on SecureRandom

SecureRandom gives us the ability to set the seed through the .setSeed() method. This method can receive either a long number or a byte array. Refrain from seeding the SecureRandom as it will almost always compromise the security of the random generator; instead let it use its internal seeding mechanism. That doesn't mean that one seed should be used indefinitely. For applications that run through a lot of random numbers you should generate a new SecureRandom periodically as this will create a new generator with new seed.

References

  1. JDK 8 Security Enhancements
  2. Secure Random Class
  3. Provider Class