Java Password Generator
Generate cryptographically secure passwords in Java using java.security.SecureRandom โ part of the standard library, no third-party dependency required.
The Secure Way
SecureRandom is backed by the JVM's platform-specific cryptographically secure random source (on most platforms, ultimately the OS CSPRNG).
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class PasswordGenerator {
private static final String UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String LOWER = "abcdefghijklmnopqrstuvwxyz";
private static final String DIGITS = "0123456789";
private static final String SYMBOLS = "!@#$%^&*()-_=+[]{}";
private static final SecureRandom RNG = new SecureRandom();
public static String generate(int length, boolean upper, boolean lower,
boolean digits, boolean symbols) {
List<String> pools = new ArrayList<>();
if (upper) pools.add(UPPER);
if (lower) pools.add(LOWER);
if (digits) pools.add(DIGITS);
if (symbols) pools.add(SYMBOLS);
if (pools.isEmpty()) throw new IllegalArgumentException("Select at least one type");
StringBuilder fullPool = new StringBuilder();
pools.forEach(fullPool::append);
List<Character> chars = new ArrayList<>();
for (String pool : pools) {
chars.add(pool.charAt(RNG.nextInt(pool.length())));
}
while (chars.size() < length) {
chars.add(fullPool.charAt(RNG.nextInt(fullPool.length())));
}
Collections.shuffle(chars, RNG); // SecureRandom-backed shuffle
StringBuilder sb = new StringBuilder();
chars.forEach(sb::append);
return sb.toString();
}
public static void main(String[] args) {
System.out.println(generate(20, true, true, true, true));
// e.g. "k7$Rt2Xz!mQ9wLp#4vNc"
}
}
The Wrong Way (Don't Do This)
java.util.Random for passwords, session tokens, or API keys. It is a linear congruential generator โ fully deterministic, and its internal state can be recovered from a small number of observed outputs.
// INSECURE โ java.util.Random is not cryptographically secure
Random random = new Random();
String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
StringBuilder password = new StringBuilder();
for (int i = 0; i < 16; i++) {
password.append(chars.charAt(random.nextInt(chars.length())));
}
Common Mistakes
- Creating a new
SecureRandom()instance per call in a hot path โ reuse a single static instance; it's thread-safe. - Calling
setSeed()with a fixed or predictable value โ this defeats the purpose of using SecureRandom in the first place. - Using
Math.random()โ internally backed by an unseededjava.util.Random, equally unsuitable for security-sensitive values. - Storing the generated password in a mutable
Stringlong-term when achar[]would let you explicitly zero it from memory after use, for extra-sensitive contexts like in-memory credential handling.
Frequently Asked Questions
java.util.Random is a linear congruential generator: fast, but fully predictable once an attacker sees a few outputs. java.security.SecureRandom draws from the platform's cryptographically secure source and is the correct choice for anything security-sensitive.
No โ instantiation can trigger OS entropy gathering and is comparatively slow. Create one static, shared instance; SecureRandom is thread-safe and designed to be reused.
No. The no-argument constructor self-seeds from the platform's entropy source. Never call setSeed() with a fixed value โ that would make the output predictable.
Prefer not to write the code?
Generate a strong password in your browser right now โ no compiler needed.
Use the Password Generator โ