Thursday, October 17, 2019

cryptographically secure pseudo-random number generator


A cryptographically secure pseudo-random number generator (CSPRNG) or cryptographic pseudo-random number generator (CPRNG) is a pseudo-random number generator (PRNG) with properties that make it suitable for use in cryptography. Most cryptographic applications require random numbers, for example:
  • Key generation
  • Nonces - "number used once” or “number once”
  • Salts in certain signature schemes, including ECDSA, RSASSA-PSS
  • IV (Initialization Vector)

Key generation :
Key generation is the process of generating keys in cryptography. A key is used to encrypt and decrypt whatever data is being encrypted/decrypted. A device or program used to generate keys is called a key generator or keygen.The key is created using a passphrase and a key generation algorithm, using a cryptographic hash function such as SHA-1.

Example:
  •     128-bits for symmetric key algorithms.
  •     1024-bits for public-key algorithms.
Nonces:
In cryptography, a nonce is an arbitrary number that can be used just once in a cryptographic communication. It is often a random or pseudo-random number issued in an authentication protocol to ensure that old communications cannot be reused in replay attacks.They can also be useful as initialization vectors and in cryptographic hash functions.Randomness or unpredictability should not be necessary.The term nonce is most often used to refer to a “random” number in a challenge-response protocol, but the required randomness properties vary.

Example :
GUID's or UUID's work well for these scenarios because the statistical probability of collisions is so low. In addition some implementations of a GUID will be based off the MAC address, time, and some random bits. This ensures that
  •     Two computers will never generate the same nonce (different MAC address)
  •     The same computer will never generate the same nonce (timestamp + random)
Salt:
In cryptography, a salt is random data that is used as an additional input to a one-way function that "hashes" data, a password or passphrase. Salts are used to safeguard passwords in storage. Historically a password was stored in plaintext on a system, but over time additional safeguards developed to protect a user's password against being read from the system. A salt is one of those methods.

Example :
Username
Salt value
String to be hashed
Hashed value = SHA256 (Salt + Password)
user1
E1F53135E559C253
password123E1F53135E559C253
72AE25495A7981C40622D49F9A52E4F156
5C90F048F59027BD9C8C8900D5C3D8
user2
84B03D034B409D4E
password12384B03D034B409D4E
B4B6603ABC670967E99C7E7F1389E40CD16
E78AD38EB1468EC2AA1E62B8BED3A


IV (Initialization Vector)
IV values are nonce as well, as the numbers are used only once. IV’s or starting variables is a fixed size input.IV and nonce are often used interchangeably. Essentially though, an IV is a nonce with an additional requirement: it must be selected in a non-predictable way. This would eliminate all sequential nonces, an IV must be random.

The big downside to an IV, as compared to a nonce, is that an IV does not afford protection against capture-replay attacks—unless you’re willing to remember every IV that has ever been used, which is not a good solution. To ensure protection against such attacks when using an IV, the higher-level protocol must have its own notion of sequence numbers that get checked in order.

Security of Random Number Generator 
Generating a nonce, initialization vector or cryptographic keying materials all require a random number. The security of basic cryptographic elements largely depends on the underlying random number generator (RNG) that was used. An RNG that is suitable for cryptographic usage is called a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG). The strength of a cryptographic system depends heavily on the properties of these CSPRNGs. Depending on how the generated pseudo-random data is applied, a CSPRNG might need to exhibit some (or all) of these properties:

  • It appears random
  • Its value is unpredictable in advance
  • It cannot be reliably reproduced after generation

In computer cryptography , keys are randomly generated using a random number generator (RNG) or pseudorandom number generator (PRNG), the latter being a computer algorithm that produces data which appears random under analysis.Some types the PRNGs algorithms utilize system entropy to generate a seed data, such seeds produce better results, since this makes the initial conditions of the PRNG much more difficult for an attacker to guess.

In Java 8, the SecureRandom class provides CSPRNG functionality. The most OS-agnostic way to generate pseudo-random data that is suitable for general cryptographic use is to rely on the OS implementation's defaults, and never to explicitly seed it (i.e., don't use the setSeed method before a call to next* methods).
//returns an unseeded instance of default RNG algorithm based on most preferred provider from list of providers configured in java.security
// On Unix like system, NativePRNG algorithm, configured with seeding from non-blocking entropy source, is returned.
// On Windows, SHA1PRNG algorithm, which can be self-seeded or explicitly seeded is returned.
SecureRandom secRan = new SecureRandom(); 
byte[] ranBytes = new bytes[20];
secRan.nextBytes(ranBytes); // since, there is no setSeed method called before a call to next* method, self-seeding occurs
The following are anti-patterns on a Windows OS and should be strictly avoided:
// ANTI-PATTERN, do not copy-paste
// On windows, default constructor would pick SHA1PRNG algorithm.
SecureRandom random1 = new SecureRandom() ; // unseeded random object
random1.setSeed(System.currentTimeMillis() % 1000); // seeding explicitly before next* methods, using low entropy source of seeding
random1.nextBytes(new byte[20]);
   
byte[] b = "123".getBytes() ;
SecureRandom random2 = new SecureRandom(b) ; // seeding with a static byte array
  
SecureRandom random4 = SecureRandom.getInstance("SHA1PRNG") ;
random4.setSeed(123); // SHA1PRNG should never be initially  explicitly seeded.
On a Unix-like OS, the following are anti-patterns and should be strictly avoided:
// ANTI-PATTERN, do not copy-paste
// Explicitly requesting SHA1PRNG and not relying on default implementation chosen
SecureRandom secRan = SecureRandom.getInstance("SHA1PRNG") ;
secRan.setSeed(12345) ; // explicitly seeding SHA1PRNG algorithm.
Cases
Provider
Algorithm
seeding
securerandom.source
1
default
default
self
default
2
default
default
explicit
default
3
default
SHA1PRNG
self
default
4
default
SHA1PRNG
explicit
default
5
default
SHA1PRNG
self
file:/custom-dev-random
6
default
SHA1PRNG
explicit
file:/ custom-dev-random
7
default
default
self
file:/ custom-dev-random
8
default
default
explicit
file:/ custom-dev-random
9
default
Windows-PRNG
self
file:/ custom-dev-random
10
default
Windows-PRNG
explicit
file:/ custom-dev-random
11
default
Windows-PRNG
self
default
12
default
Windows-PRNG
explicit
default

where default values are, Provider:SUN, Algorithm :Linux-NativePRNG,Windows-SHA1PRNG, securerandom.source:file:/dev/random, seeding:self

Conclusion : 
  • SHA1PRNG algorithm, when explicitly seeded, pseudo-random output generated would be directly proportional to the entropy source provided. We always want entropy source to be provided by underlying OS. 
  • Thus, for Unix/Linux: default implementation selected would be NativePRNG and allow it to be self seeded. However, for windows default implementation selected would be SHA1PRNG, which with explicit seeding might reduce entropy. Thus, always choose an algorithm when running on Windows.
  • Unfortunately, explicitly selecting a windows specific algorithm on windows and letting JDK choose algorithm for Unix like systems, makes it less portable across Unix like systems and Windows.

Most secure and portable way of using SecureRandom,
In Unix like OS is:
SecureRandom secRan = new SecureRandom() ; // In Unix like systems, default constructor uses NativePRNG, seeded by securerandom.source property
byte[] b = new byte[NO_OF_RANDOM_BYTES] ;
secRan.nextBytes(b);

In Windows:
SecureRandom secRan = SecureRandom.getInstance("Windows-PRNG") ; // Default constructor would have returned insecure SHA1PRNG algorithm, so make an explicit call.
byte[] b = new byte[NO_OF_RANDOM_BYTES] ;
secRan.nextBytes(b);
Example :
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Base64 ;
import javax.crypto.KeyGenerator;


public class TestCrypto {
                
        public static final int NO_OF_RANDOM_BYTES = 20 ;
        public static final int KEY_SIZE = 256 ;
        public static void main( String args[] ) {
                
                SecureRandom secRan = null ;

                // Case 1      
                try {                    
                     secRan = new SecureRandom() ; // SecureRandom default constructor will always use default provider and algorithm.
                    printRandomnessParameters(secRan, "1. Using default algorithm, securerandom.source and self-seeding " );
                } catch(NoSuchAlgorithmException nsae) {System.out.println("Algorithm " + secRan.getAlgorithm() + " is not available on this system") ;}    

                // Case 2
                try {        
                    secRan = new SecureRandom() ;
                    secRan.setSeed(12345); // To see effects of using a low entropy source on pseudo random data generated and Key Generation, used such a static value.
                    printRandomnessParameters(secRan, "2. Using default algorithm, securerandom.source and explicit seeding " );
                } catch(NoSuchAlgorithmException nsae) {System.out.println("Algorithm " + secRan.getAlgorithm() + " is not available on this system") ;}    
                
                // Case 3
                try {                    
                    secRan = SecureRandom.getInstance("SHA1PRNG") ;
                    printRandomnessParameters(secRan, "3. Using SHA1PRNG algorithm, default value of securerandom.source and self-seeding " );
                } catch(NoSuchAlgorithmException nsae) {System.out.println("Algorithm " + secRan.getAlgorithm() + " is not available on this system") ;}    

                // Case 4
                try {                    
                    secRan = SecureRandom.getInstance("SHA1PRNG") ;
                    secRan.setSeed(12345) ;
                    printRandomnessParameters(secRan, "4. Using SHA1PRNG algorithm, default value of securerandom.source and explicit seeding " );
                } catch(NoSuchAlgorithmException nsae) {System.out.println("Algorithm " + secRan.getAlgorithm() + " is not available on this system") ;}    

                // Case 5
                try {                                        
                    secRan = SecureRandom.getInstance("SHA1PRNG") ;
                    Security.setProperty("securerandom.source", "file:/custom-dev-random");
                    printRandomnessParameters(secRan, "5. Using SHA1PRNG algorithm, changing securerandom.source value and self-seeding " );
                } catch(NoSuchAlgorithmException nsae) {System.out.println("Algorithm " + secRan.getAlgorithm() + " is not available on this system") ;}    

                // Case 6
                try {                    
                    secRan = SecureRandom.getInstance("SHA1PRNG") ;
                    secRan.setSeed(12345) ;
                    printRandomnessParameters(secRan, "6. Using SHA1PRNG algorithm, changing securerandom.source value and explicit seeding " );
                } catch(NoSuchAlgorithmException nsae) {System.out.println("Algorithm " + secRan.getAlgorithm() + " is not available on this system") ;}    

                // Case 7
                try {                    
                    secRan = new SecureRandom() ;
                    printRandomnessParameters(secRan, "7. Using default algorithm, changing securerandom.source value and self-seeding " );
                } catch(NoSuchAlgorithmException nsae) {System.out.println("Algorithm " + secRan.getAlgorithm() + " is not available on this system") ;}    
               
                // Case 8
                try {                    
                    secRan = new SecureRandom() ;
                    secRan.setSeed(12345) ;
                    printRandomnessParameters(secRan, "8. Using default algorithm, changing securerandom.source value and explicit-seeding " );
                } catch(NoSuchAlgorithmException nsae) {System.out.println("Algorithm " + secRan.getAlgorithm() + " is not available on this system") ;}    
                
                // Case 9   
                try {          
                    secRan = SecureRandom.getInstance("Windows-PRNG") ;
                    printRandomnessParameters(secRan, "9. Using Windows-PRNG algorithm, changing securerandom.source value and self-seeding " );
                } catch(NoSuchAlgorithmException nsae) {System.out.println("Algorithm " + "Windows-PRNG" + " is not available on this system") ;}    


                // Case 10
                try {                    
                    secRan = SecureRandom.getInstance("Windows-PRNG") ;
                    secRan.setSeed(12345);
                    printRandomnessParameters(secRan, "10. Using Windows-PRNG algorithm, changing securerandom.source value and explicit seeding " );
                } catch(NoSuchAlgorithmException nsae) {System.out.println("Algorithm " + "Windows-PRNG" + " is not available on this system") ;}    

                // Case 11          
                try {                    
                    secRan = SecureRandom.getInstance("Windows-PRNG") ;
                    Security.setProperty("securerandom.source", "file:/dev/random");           
                    printRandomnessParameters(secRan, "11. Using Windows-PRNG algorithm, default securerandom.source value and self-seeding " );
                } catch(NoSuchAlgorithmException nsae) {System.out.println("Algorithm " + "Windows-PRNG" + " is not available on this system") ;}        
                
                // Case 12
                try {                    
                    secRan = SecureRandom.getInstance("Windows-PRNG") ;
                    secRan.setSeed(12345) ;           
                    printRandomnessParameters(secRan, "12. Using Windows-PRNG algorithm, default securerandom.source value and explicit seeding " );
                } catch(NoSuchAlgorithmException nsae) {System.out.println("Algorithm " + "Windows-PRNG" + " is not available on this system") ;}    
        }

        
        //This method, prints the value of various parameters used like provider, CSPRNG algorithm, randomness source. It also prints effect of using secRan on a Symmetric Key to see if its truly random.
        private static void printRandomnessParameters(SecureRandom secRan, String prefixMessage) throws NoSuchAlgorithmException {
                System.out.println(prefixMessage + " : " + "SecureRandom() Provider : " + secRan.getProvider().getName() + " Algorithm " + secRan.getAlgorithm() + " randomness source " + Security.getProperty("securerandom.source"));

               byte[] b = new byte[NO_OF_RANDOM_BYTES];
               secRan.nextBytes(b);
              
               System.out.println("Randomizer bytes = " + Base64.getEncoder().encodeToString(b) ) ;
              
               KeyGenerator symmKeyGen = KeyGenerator.getInstance("AES") ;
               symmKeyGen.init(KEY_SIZE,secRan) ;

               System.out.println("Key generated = " + Base64.getEncoder().encodeToString(symmKeyGen.generateKey().getEncoded())) ;

               System.out.println("==========================");

        }
}
Windows :
1. Using default algorithm, securerandom.source and self-seeding  : SecureRandom() Provider : SUN Algorithm SHA1PRNG randomness source file:/dev/random
Randomizer bytes = HbEfUg/xhVOaefeCPQOpJGmvVyM=
Key generated = mLhxRA+Iv9gl8H4Caa6PpoaNBz2Bq+yLpIkGsNCN54A=
==========================
2. Using default algorithm, securerandom.source and explicit seeding  : SecureRandom() Provider : SUN Algorithm SHA1PRNG randomness source file:/dev/random
Randomizer bytes = UHVRUm2SFU7Zvz9ljbfeSbeO1XM=
Key generated = bwArq5zsJbVrgLJtPmg1QCsoyV6Z1aXTN+s+XNcjnx0=
==========================
3. Using SHA1PRNG algorithm, default value of securerandom.source and self-seeding  : SecureRandom() Provider : SUN Algorithm SHA1PRNG randomness source file:/dev/random
Randomizer bytes = GFRsCiOCtILrbIoROzcXRReKj0o=
Key generated = DvGXflEmWZJPdiNnNSXjc8tT/Z2IGWrad6YYjE6mx/Y=
==========================
4. Using SHA1PRNG algorithm, default value of securerandom.source and explicit seeding  : SecureRandom() Provider : SUN Algorithm SHA1PRNG randomness source file:/dev/random
Randomizer bytes = UHVRUm2SFU7Zvz9ljbfeSbeO1XM=
Key generated = bwArq5zsJbVrgLJtPmg1QCsoyV6Z1aXTN+s+XNcjnx0=
==========================
5. Using SHA1PRNG algorithm, changing securerandom.source value and self-seeding  : SecureRandom() Provider : SUN Algorithm SHA1PRNG randomness source file:/something-other-than-dev-random
Randomizer bytes = 8dwhVFBON77pMmT+drgwI8PINRc=
Key generated = tGaZ4Gweakjmk0uSNRV4WpSZWdRIWOJZ1zjytn7r1SQ=
==========================
6. Using SHA1PRNG algorithm, changing securerandom.source value and explicit seeding  : SecureRandom() Provider : SUN Algorithm SHA1PRNG randomness source file:/something-other-than-dev-random
Randomizer bytes = UHVRUm2SFU7Zvz9ljbfeSbeO1XM=
Key generated = bwArq5zsJbVrgLJtPmg1QCsoyV6Z1aXTN+s+XNcjnx0=
==========================
7. Using default algorithm, changing securerandom.source value and self-seeding  : SecureRandom() Provider : SUN Algorithm SHA1PRNG randomness source file:/something-other-than-dev-random
Randomizer bytes = BLBHLbzfiQenw20mAT49RnUobNo=
Key generated = YN8OM+sfTYUhWmgkTJ825ZjYDqwVdl6bHEBTaXTFhUE=
==========================
8. Using default algorithm, changing securerandom.source value and explicit-seeding  : SecureRandom() Provider : SUN Algorithm SHA1PRNG randomness source file:/something-other-than-dev-random
Randomizer bytes = UHVRUm2SFU7Zvz9ljbfeSbeO1XM=
Key generated = bwArq5zsJbVrgLJtPmg1QCsoyV6Z1aXTN+s+XNcjnx0=
==========================
9. Using Windows-PRNG algorithm, changing securerandom.source value and self-seeding  : SecureRandom() Provider : SunMSCAPI Algorithm Windows-PRNG randomness source file:/something-other-than-dev-random
Randomizer bytes = cgjt29F3qmfibiICTj3VSuYOh2Q=
Key generated = Ay3Q5+ZhT0sN+WMFaXS3RmKTLJd4rK1/MdNP25IRNno=
==========================
10. Using Windows-PRNG algorithm, changing securerandom.source value and explicit seeding  : SecureRandom() Provider : SunMSCAPI Algorithm Windows-PRNG randomness source file:/something-other-than-dev-random
Randomizer bytes = lJx12nApZzSYkS02stT+2MbB2yM=
Key generated = a9jDj214VcnOVGmV5x3q9IByQBQFcXPnEuvA0RxqJhk=
==========================
11. Using Windows-PRNG algorithm, default securerandom.source value and self-seeding  : SecureRandom() Provider : SunMSCAPI Algorithm Windows-PRNG randomness source file:/dev/random
Randomizer bytes = 06K/4XEUiQOHRLXgEPOAjWrACJ0=
Key generated = 6pg3Cv1Wo3+dIyVydZC97wSjvwXvChxmO8P3DoLBTvQ=
==========================
12. Using Windows-PRNG algorithm, default securerandom.source value and explicit seeding  : SecureRandom() Provider : SunMSCAPI Algorithm Windows-PRNG randomness source file:/dev/random
Randomizer bytes = Oe8vAHwhVJLXC0A9BeMN/WbbQ1g=
Key generated = IcXqhhomjhXeLvVsQdCOXsTTAO7+SY0IooDX0OUDbmI=
==========================

Linux :
1. Using default algorithm, securerandom.source and self-seeding  : SecureRandom() Provider : SUN Algorithm NativePRNG randomness source file:/dev/random
Randomizer bytes = hXJnGpQvs0BNa4jSdkGw5tsZqqI=
Key generated = 9DkgtSZ3r6uZibLobwr61Gc1te6hj+BDNN91BU27hKI=
==========================
2. Using default algorithm, securerandom.source and explicit seeding  : SecureRandom() Provider : SUN Algorithm NativePRNG randomness source file:/dev/random
Randomizer bytes = DpVHrubgtHrUJZLGXCly2N0xgwQ=
Key generated = L/cEJcUzgIrOkPH/T+Q6TGBHz5wMwoFTgB4pW7KemA0=
==========================
3. Using SHA1PRNG algorithm, default value of securerandom.source and self-seeding  : SecureRandom() Provider : SUN Algorithm SHA1PRNG randomness source file:/dev/random
Randomizer bytes = pVLkfvnhflWeRwtm44penYNnVqk=
Key generated = STiquBElX+biACtTj85EcVNYhA2GFaophx+qMHTBuSs=
==========================
4. Using SHA1PRNG algorithm, default value of securerandom.source and explicit seeding  : SecureRandom() Provider : SUN Algorithm SHA1PRNG randomness source file:/dev/random
Randomizer bytes = UHVRUm2SFU7Zvz9ljbfeSbeO1XM=
Key generated = bwArq5zsJbVrgLJtPmg1QCsoyV6Z1aXTN+s+XNcjnx0=
==========================
5. Using SHA1PRNG algorithm, changing securerandom.source value and self-seeding  : SecureRandom() Provider : SUN Algorithm SHA1PRNG randomness source file:/something-other-than-dev-random
Randomizer bytes = ec7Rme9wJ7+sriqLfaFYylioiSg=
Key generated = awdoe/wTn76/znM/3f6i8ZfV+1Oxd7qb82PKGbm7ujM=
==========================
6. Using SHA1PRNG algorithm, changing securerandom.source value and explicit seeding  : SecureRandom() Provider : SUN Algorithm SHA1PRNG randomness source file:/something-other-than-dev-random
Randomizer bytes = UHVRUm2SFU7Zvz9ljbfeSbeO1XM=
Key generated = bwArq5zsJbVrgLJtPmg1QCsoyV6Z1aXTN+s+XNcjnx0=
==========================
7. Using default algorithm, changing securerandom.source value and self-seeding  : SecureRandom() Provider : SUN Algorithm NativePRNG randomness source file:/something-other-than-dev-random
Randomizer bytes = 2nvbo2yK7wY+kRnZ+9K8azPq9/A=
Key generated = n1vRoO7QBaE063zMs0dIuqUdS1TQrhMmthcwvq6cmpE=
==========================
8. Using default algorithm, changing securerandom.source value and explicit-seeding  : SecureRandom() Provider : SUN Algorithm NativePRNG randomness source file:/something-other-than-dev-random
Randomizer bytes = R9DAG4WIVSqZ3ZJxDDHosrsnxOY=
Key generated = 4QW3RyAI9B8WFJUgYwsZ8cM559/ajAKOr18aQYnZr1Q=
==========================
Algorithm Windows-PRNG is not available on this system
Algorithm Windows-PRNG is not available on this system
Algorithm Windows-PRNG is not available on this system
Algorithm Windows-PRNG is not available on this system
Sources of Entropy :

Entropy pool is used as a source of randomness needed for operations like encryption. It is a large number (typically 4096 bits) stored in a location to be read by programs. It harness actual noise from hardware sources (variance in fan noise or HDD) like mouse movements, key press, IDE or specially provided randomness generators to generate random number.

Whenever somebody reads from the pool the entropy (the measure of randomness) is reduced because the user will know more information about the pool. So the kernel need to replenish the pool with more randomness from hardware sources.


Entropy is basically the randomness collected by the Linux Kernel.The Linux kernel generates entropy from keyboard timings, mouse movements, and IDE timings and makes the random character data available to other operating system processes through the special files /dev/random and /dev/urandom. A lack of entropy can have a negative impact on performance and security.

The estimate of the entropy of the pool is kept in a file on this path /proc/sys/kernel/random/entropy_avail


In Unix-like systems, the file://dev/random and file://dev/urandom files are continuously updated with random external OS-dependent events.

In most operating systems, the entropy pool used for seeding a randomizer comes in one of these two forms:
  • Blocking: blocks your application until it finds sufficient entropy in its entropy pool. In Unix-like systems, this comes from file://dev/random
  • Non-Blocking:  doesn't block the application, and works with whatever is available in your OS's entropy pool. In Unix-like systems, it comes from file://dev/urandom
Cryptographers tends to be pessimistic about their entropy sources but for most purposes using a non-blocking source of entropy seeding should suffice. All providers and algorithms the Java provides are cryptographically secured as long as they are initially seeded with the highest-entropy source possible. The recommended code sample above takes care of this by providing a default implementation that is seeded from a non-blocking entropy pool.

There are a few ways that you can choose between these two pools in your application:
Configuring the securerandom.source (default is /dev/urandom) property in the java.security config file.
#Chosen algorithm would be seeded with a blocking entropy pool
securerandom.source=file:/dev/random
or
#Chosen algorithm would be seeded with a non-blocking entropy pool
securerandom.source=file:/dev/urandom
Passing the System property java.security.egd to your application's command line.
#Blocking entropy pool would be used by SecureRandom in MainClass
% java -Djava.security.egd=file:/dev/random MainClass
or 
#Non-Blocking entropy pool would be used by SecureRandom in MainClass
% java -Djava.security.egd=file:/dev/urandom MainClass
Using the SecureRandom.getInstance(algo) method and explicitly specifying an algorithm. In Unix-like OSes, NativePRNG and NativePRNGNonBlocking algorithms are seeded with non-blocking entropy pools, and the NativePRNGBlocking algorithm is seeded with a blocking source of entropy.
// On Unix like OS, NativePRNG algorithm, is being returned, which is self-seeded with non-blocking (file://dev/urandom) source of entropy.
SecureRandom nativePrng = SecureRandom.getInstance("NativePRNG");
or
// On Unix like OS, NativePRNGBlocking algorithm, is being returned, which is self-seeded with blocking (file://dev/random) source of entropy.
SecureRandom nativePrngNon = SecureRandom.getInstance("NativePRNGBlocking");
SecureRandom.getInstanceStrong method (available since Java 8). When this method is used, it picks up the algorithm or algorithm/provider configuration in securerandom.strongAlgorithms java.security config. By default, it is configured to use non-blocking.
// Algorithm used, is based on what is configured in securerandom.strongAlgorithms property of java.security config file. By default it's configured to use blocking algorithm.
SecureRandom strongRNG = SecureRandom.getInstanceStrong() ;
On Unix-like system, securerandom.strongAlgorithm is configured as:
#This is a comma-separated list of algorithm and/or algorithm:provider entries.
securerandom.strongAlgorithms=NativePRNGBlocking:SUN
A healthy Linux system with a lot of entropy available will have returned close to the full 4,096 bits of entropy. This is always a truth. If the pool runs low you’ll immediately start having weird problems with SSH/SSL servers, cron jobs can and have gone south, especially if the value returned is less than 200, the system is running low on entropy.

/dev/random blocks the thread if there isn't enough randomness available, but /dev/urandom will never block.There is no advantage in using /dev/random over /dev/urandom. They use the same pool of randomness under the hood. They are equally secure. If you want to safely generate random numbers, you should use /dev/urandom.

The only time you would want to call /dev/random is when the machine is first booting, and entropy has not yet accumulated. Most systems will save off entropy before shutting down so that some is available when booting, so this is not an issue if you run directly on hardware.


Below high lighted buckle points are where application is taking more time (copied above) to create a new oracle connection while initializing connection pooling and entropy counts reduced to Zero. Due to lack of entropy's , OS entropy pool was blocked to provide secure random number.


In this case , every time connection was created with in few milli Seconds and there was no more use of entropy from Entropy Pool.


References :
https://securitytraning.com/linux-kernel-entropy/
https://www.veracode.com/blog/research/cryptographically-secure-pseudo-random-number-generator-csprng
https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator
https://www.geeksforgeeks.org/random-vs-secure-random-numbers-java/

No comments:

Post a Comment