Is there a java equivalent to OpenSSL's bn_rand_range?

杀马特。学长 韩版系。学妹 提交于 2019-12-23 17:31:16

问题


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 2bits). 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?

P.S. 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.


回答1:


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));
    }
}



回答2:


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


来源:https://stackoverflow.com/questions/9441598/is-there-a-java-equivalent-to-openssls-bn-rand-range

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!