SecureRandom Implementation ( – SHA1PRNG)

January 15, 2014

My previous blog entry on SecureRandom was Issues to be aware of when using Java’s SecureRandom. Today, I’ll write about the most complex SecureRandom implementation I’ve seen so far.


This implementation is the default SecureRandom implementation in Oracle JRE installations on Windows. If it is configured to not be the default, it can be instantiated using:“SHA1PRNG”, “SUN”);

Initial Seeding (Default)

This implementation of SecureRandom can be seeded using two mechanisms (when default configurations are used – non-default configurations will be discussed later):

  • If a seed is not specified when instantiating a SecureRandom object, and the caller attempts to get output from the PRNG, it seeds itself automatically. It seeds itself using a static SecureRandom instance that is a member variable in the class. The static instance is seeded using, which may get entropy from an external source. This means that this implementation only retrieves entropy from an external source once; any SecureRandom instances that are created afterwards are seeded using outputs from the static SecureRandom instance. By default, the static SecureRandom instance is seeded as follows:
    • On Windows, SeedGenerator.getSystemEntropy() as well as the Windows CryptGenRandom() function are used.
    • On *nix, SeedGenerator.getSystemEntropy() as well as /dev/random are used. Note that since reads from /dev/random can block if insufficient entropy is available, the first time a SecureRandom object is seeded, the thread attempting to initialize the object could hang.
  • If a seed is specified using setSeed() before any output is obtained from the PRNG, only the specified seed will be used for the PRNG, and the self-seeding mechanism using the static SecureRandom instance will be bypassed.

PRNG Output

The output of the SHA1PRNG is generated using applications of the SHA-1 hash function.

Other Seed Generation (Default)

If generateSeed() is called, the Windows CryptGenRandom() function is used to generate a seed on Windows, and /dev/random is used to generate a seed on *nix by default. Since reads from /dev/random can block if insufficient entropy is available, the seed generation operation on *nix could hang.

Note that unlike what the Javadocs at state, the mechanism used to generate this seed is not the same as the mechanism used to seed SecureRandom instances as described in an earlier section. It is similar to the way in which the static SecureRandom instance is seeded; however, SeedGenerator.getSystemEntropy() is not used here.

Seed Generation (Non-Default Configurations)

The implementation contains a static SecureRandom instance that is used to seed SHA1PRNG instances generated for callers. The static instance is seeded using Depending on the Java Virtual Machine’s configuration, the actual seeding mechanism may vary. The various mechanisms are described in the subsections below.


Regardless of the configuration, the SeedGenerator.getSystemEntropy() method is always used as part of the seed. This method outputs a SHA-1 hash of the following:

  • One byte from System.currentTimeMillis();
  • All system properties (name/value pairs)
  • InetAddress.getLocalHost().toString().getBytes()
  • List of files/directories in
  • Exception.hashCode (if an Exception occurs while gathering any of the above values; if an Exception does occur, some of the above values may not be included in the hash)
  • Runtime.getRuntime().totalMemory()
  • Runtime.getRuntime. freeMemory()

The following values are used to determine where the rest of the seed entropy is obtained:

  • The system property
  • The securerandom.source property in the file

The system property takes precedence. By default, is not defined, and securerandom.source is set to file:/dev/urandom. The value set by these properties will be referred to as egdSource below. The seeding mechanisms are chosen as follows:

  • If egdSource is set to file:/dev/urandom or file:/dev/random, then is used.
  • If egdSource is set to some other value, then the given file/URL is used with
  • If egdSource is not specified or if the mechanism chosen above fails, then is used.


The *nix implementation uses with /dev/random. This results in the seed being read from /dev/random. Note that since reads from /dev/random can block if insufficient entropy is available, the seed generation operation on *nix could hang.

The Windows implementation uses the Windows CryptGenRandom() function to generate the seed.


This implementation reads from the given URL (which could be a local file) and returns the first bytes at the URL as the seed.


This implementation spawns a thread that runs for approximately 250ms, and counts the number of times a loop executes while the thread is running. This results in one byte of unpredictable output being generated. This seed generator is quite slow and generates at most 4 bytes per second. Seeding a SHA1PRNG instance using this mechanism takes at least 5 seconds.


The implementation is the most complex SecureRandom implementation I’ve seen so far in terms of the number of ways in which it can be configured and used. In general, it works as expected, but there are a few configuration and usage issues to be aware of:

  • Always obtain some output from the PRNG before calling setSeed()
  • On *nix, be aware that the creating the very first instance of SecureRandom or calling generateSeed() could cause your thread to hang – if the default configuration is used
  • If egdSource is set to a file/URL with predictable data, the outputs of SecureRandom could become predictable
  • If egdSource is set to an invalid file/URL, a very slow seeding mechanism is used as a backup that could cause a temporary Denial of Service
By Amit Sethi Principal Consultant View Bio

Amit Sethi, Principal Consultant, has been with Cigital since 2004. He specializes in Mobile Security, Online Game Security and Cryptography. Amit’s work includes extracting cryptographic keys from embedded devices using side-channel attacks, designing mechanisms to make those attacks more difficult, and designing a format-preserving encryption algorithm based on well-studied cryptographic primitives for a Fortune 500 company. Even in his free time, Amit enjoys reverse engineering binaries, analyzing open source software, and experimenting with new technologies. Words of Security Wisdom: Just because you don’t know of any security incidents in your software/environment doesn’t mean that you haven’t had any security incidents –especially if you don’t have good monitoring controls in place.

Cigital is one of the world’s largest application security firms. We go beyond traditional testing services to help our clients find, fix and prevent vulnerabilities in the applications that power their business.

Our experts also provide remediation guidance, program design services, and training that empower you to build and maintain secure applications.

Learn More
Subscribe to our Blog
2015 (71)
2014 (44)
2013 (8)
2012 (3)
2011 (8)
2010 (2)
2009 (3)
2008 (3)
2007 (8)
2004 (2)