Do not use standard pseudo-random number generators, such as those used in mathematics to generate pseudo-random numbers.
Clarification
Standard pseudo-random number generators can not withstand cryptographic attacks because such generators are based on functions that produce predictable values.
Make sure the seed that is used to initialize a generator has enough entropy.
Periodically reinitialize seeds.
Cryptographically strong random generators
Use the crypto/rand package to generate cryptographically strong random values in Go.
Starting with JDK8, use SecureRandom.getInstanceStrong() to get a SecureRandom instance that implements a strong generation algorithm. For a UNIX-like OS, the default strong generation algorithm is NativePRNGBlocking, which is based on /dev/random. As a result, SecureRandom.getInstanceStrong() will return a SecureRandom implementation that can block a thread when the generateSeed or nextBytes methods are called. Use NativePRNGNonBlocking to avoid possible thread blocking.
// JDK8+
try {
// UNIX-like and Windows
// possible thread blocking for a UNIX-like OS
SecureRandom secureRandomStrong = SecureRandom.getInstanceStrong();
byte[] bytes = new byte[16];
secureRandomStrong.nextBytes(bytes);
// UNIX-like (without thread blocking)
SecureRandom secureRandomNative = SecureRandom.getInstance("NativePRNGNonBlocking");
byte[] bytes = new byte[16];
secureRandomNative.nextBytes(bytes);
} catch(NoSuchAlgorithmException e) {
throw new RuntimeException("Failed to instantiate random number generator", e);
}
For older versions of the JDK for UNIX-like OS, create a SecureRandom instance using the default constructor. However, in this case, calling the generateSeed method may cause thread blocking. For Windows, use Windows-PRNG.
// JDK <= 7
try {
// Unix-like
SecureRandom secureRandom = new SecureRandom();
byte[] bytes = new byte[16];
secureRandom.nextBytes(bytes);
// Windows
SecureRandom secureRandomWindows = SecureRandom.getInstance("Windows-PRNG");
byte[] bytes = new byte[16];
secureRandomWindows.nextBytes(bytes);
} catch(NoSuchAlgorithmException e) {
throw new RuntimeException("Failed to instantiate random number generator", e);
}
Avoid using the SHA1PRNG generation algorithm. If it is necessary to use SHA1PRNG:
Generate random values of length <= 20 bytes.
Create a new instance of SecureRandom for each generation.
try {
SecureRandom sha1Random = SecureRandom.getInstance("SHA1PRNG");
byte[] bytes = new byte[20];
sha1Random.nextBytes(bytes);
// new instance for new generation
sha1Random = SecureRandom.getInstance("SHA1PRNG");
sha1Random.nextBytes(bytes);
} catch(NoSuchAlgorithmException e) {
throw new RuntimeException("Failed to instantiate random number generator", e);
}
Use the crypto package to generate cryptographically strong random values.