skip to content

What is the difference between new SecureRandom() (the default instance) and SecureRandom.getInstanceStrong(), and when would you use each?

level: seniorimportance: should knowfreq 55%

answer

  1. Default new SecureRandom() = fast, non-blocking, fine for almost all
  2. getInstanceStrong() reads securerandom.strongAlgorithms property
  3. strong = may BLOCK on low entropy (historically /dev/random)
  4. Use strong for rare long-lived keys, not high-volume tokens
  5. Both are CSPRNGs; 'strong' is not 'the only secure one'

basics

~10 s

new SecureRandom() gives a strong, non-blocking generator good for almost everything. getInstanceStrong() returns a platform-configured 'strong' algorithm that may block waiting for entropy; reserve it for rare, very high-value secrets like long-lived keys.

solid answer

~50 s

Both produce cryptographically secure output, but they differ in selection and blocking behavior. new SecureRandom() (or SecureRandom.getInstanceStrong's non-strong counterpart) picks the highest-priority registered SecureRandom algorithm — on Linux typically NativePRNG reading from a non-blocking OS source. It is fast and suitable for nearly all security work: tokens, salts, IVs, session ids. SecureRandom.getInstanceStrong() consults the securerandom.strongAlgorithms security property and returns whatever the platform deems 'strong'; historically this could map to a blocking source (like /dev/random) that waits for fresh OS entropy, which can stall under low entropy. Use getInstanceStrong() sparingly for the rare, highest-value, long-lived secrets (e.g. a permanent root/CA key) where you want the platform's strongest configuration and can tolerate a possible delay. For high-volume generation, prefer new SecureRandom() to avoid blocking. On modern Linux the practical entropy-starvation risk is largely gone, but the API contract (strong = possibly blocking) still guides the choice.

code

java · 16 lines
java
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

class RandomChoice {
    // Default: fast, non-blocking — use for tokens, salts, IVs, sessions.
    static final SecureRandom DEFAULT = new SecureRandom();

    // Strong: platform's strongest source, MAY BLOCK on low entropy.
    // Reserve for rare, long-lived, high-value secrets.
    static byte[] longLivedRootKey() throws NoSuchAlgorithmException {
        SecureRandom strong = SecureRandom.getInstanceStrong();
        byte[] key = new byte[32]; // 256-bit
        strong.nextBytes(key);
        return key;
    }
}

go deeper

for a junior

Knows new SecureRandom() is the safe default and that getInstanceStrong() exists for extra-strong cases.

for a middle

Can state that default is non-blocking and fine for tokens, while getInstanceStrong() may block and is for rare high-value secrets.

for a senior

Explains the provider/strongAlgorithms selection mechanism, the blocking-on-low-entropy contract, and chooses correctly for throughput vs. one-off keys.

for a principal

Reasons about entropy across platforms/containers, configures securerandom.strongAlgorithms or DRBG for FIPS/compliance, and sets policy on where each is used.

## Background: how SecureRandom is selected `SecureRandom` is part of the **JCA (Java Cryptography Architecture)**, a provider framework. The JVM has one or more **security providers** (e.g. SUN, SunPKCS11) that *register implementations* of services like `SecureRandom` under named **algorithms** (e.g. `NativePRNG`, `SHA1PRNG`, `DRBG`, `Windows-PRNG`). When you ask for a SecureRandom, the framework finds a registered implementation. ## new SecureRandom() — the default `new SecureRandom()` returns an instance using the **first/highest-priority** `SecureRandom` algorithm registered by the installed providers, for the current platform: - On Linux this is usually **NativePRNG**, which reads the OS CSPRNG (`/dev/urandom`-style, **non-blocking**). - On Windows it's typically a Windows-PRNG / DRBG. It is **fast** and **non-blocking** and is the right default for essentially all application security needs: session tokens, CSRF tokens, password-reset tokens, salts, IVs, nonces, even most key generation. ## SecureRandom.getInstanceStrong() — the 'strong' selector `SecureRandom.getInstanceStrong()` is a static factory that does **not** let you name an algorithm. Instead it reads the JDK security property **`securerandom.strongAlgorithms`** (configured in `java.security`) and returns an instance of the first algorithm listed there. The intent: 'give me whatever this platform considers its strongest source.' The catch is the **blocking** contract. Historically, the 'strong' algorithm on Unix could be one that draws from a **blocking entropy pool** (conceptually `/dev/random`): if the OS estimates it has insufficient fresh entropy, the call **blocks until more is gathered**. On a freshly booted or headless machine this can cause noticeable stalls or hangs. So the JDK documents getInstanceStrong() as suitable for generating, e.g., long-lived high-value keys where you call it rarely and can tolerate a wait. ## How to choose | Need | Use | |---|---| | Tokens, salts, IVs, session ids, high volume | `new SecureRandom()` (fast, non-blocking) | | A rare, long-lived, highest-value secret (root/CA key) | `SecureRandom.getInstanceStrong()` | Generating many values with getInstanceStrong() risks **blocking under low entropy** and hurting throughput/availability. Conversely, the default is already a CSPRNG, so it is not 'weak' — 'strong' just means 'platform's strongest configured source, possibly blocking.' ## Modern reality On current Linux kernels the kernel CSPRNG is properly seeded early and `getrandom()` semantics mean entropy starvation is largely a non-issue in practice; many setups make even the 'strong' source non-blocking after boot. Still, the **API contract** (strong = may block) and portability across platforms mean the guidance above remains the safe mental model. You can also override `securerandom.strongAlgorithms` for your platform if you have specific requirements. ## Other ways to obtain instances - `SecureRandom.getInstance("DRBG")` (or another named algorithm) — explicitly pick an algorithm/provider, useful for FIPS or reproducible deployments. - `new SecureRandom()` — let the platform choose; the usual default.

  • Which security property controls what getInstanceStrong() returns?
    securerandom.strongAlgorithms in the JDK's java.security configuration; getInstanceStrong() returns an instance of the first algorithm listed there for the platform.
  • Why can getInstanceStrong() hang on a freshly booted server?
    The 'strong' algorithm may draw from a blocking entropy source that waits until the OS has gathered enough fresh entropy; on a new/headless host that pool can be slow to fill, blocking the call.

saying these in an interview costs you the question

  • Calling getInstanceStrong() in a hot path for every token (blocking risk)
  • Thinking new SecureRandom() is insecure and only 'strong' is safe
  • Assuming getInstanceStrong() lets you pass an algorithm name
  • Ignoring that 'strong' can block and cause production hangs on fresh hosts

context