简体   繁体   中英

Is there a java equivalent to OpenSSL's bn_rand_range?

Specifically, I just want to generate a cryptographically secure random number between 0 and some number x .

In OpenSSL this is done with the function bn_range .

I can implement it myself using Java's BigInteger(int bits, Random r) constructor (which generates a number from 0 to 2 bits ). But I would like, if possible, to use a better tested algorithm for the sake of security.

Is there a standard way to do this in Java?

PS I am actually using Android, but I don't know how to do it in standard Java.

EDIT: x is a large integer stored as a BigInteger .

Java provides a subclass of the Random class, the SecureRandom class. The description includes:

This class provides a cryptographically strong random number generator (RNG). Many implementations are in the form of a pseudo-random number generator (PRNG), which means they use a deterministic algorithm to produce a pseudo-random sequence from a true random seed. Other implementations may produce true random numbers and yet others may use a combination of both techniques

Java provides just one implementation, the SHA1PRNG function, which it details as a pseudo-random number generation (PRNG) algorithm:

This implementation follows the IEEE P1363 standard, Appendix G.7: "Expansion of source bits", and uses SHA-1 as the foundation of the PRNG. It computes the SHA-1 hash over a true-random seed value concatenated with a 64-bit counter which is incremented by 1 for each operation. From the 160-bit SHA-1 output, only 64 bits are used.

It should also be noted that the bn_rand_range function from OpenSSL is also considered to use a pseudo-random number generation (PRNG) algorithm, though I could not find details as for to what algorithm the function implements.

Because SecureRandom is a subclass of the Random class, SecureRandom objects can use all the methods of Random including the .nextInt(int n) method. The nextInt method provides:

Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence.

Therefore, to generate a cryptography strong pseudo-random number in the range of (0,100] you can use code like the following:

import java.security.SecureRandom;
class secure{
    public static void main(String[] args) throws Exception{
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        System.out.println(random.nextInt(100));
    }
}

As far as I can tell, this functionality is not provided. But it is easy enough to implement yourself.

Random r = new SecureRandom();    
BigInteger q = something_big;
BigInteger ans;

do
    ans = BigInteger(bits_in_q, r);
while (ans.compareTo(q) >= 0); // bn_rand_range generates numbers < q

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM