Java中是否有类似于OpenSSL的bn_rand_range函数?

3

具体来说,我只想产生一个在0到某个数字x之间具有密码学安全性的随机数。

在OpenSSL中,可以使用函数bn_range来实现。

我可以使用Java的BigInteger(int bits, Random r)构造函数自己实现(它生成从0到2bits的数字)。但出于安全考虑,我希望如果可能的话,使用经过更好测试的算法。

在Java中是否有标准的方法来完成这个任务?

P.S. 我实际上正在使用Android,但我不知道如何在标准的Java中实现它。

编辑:x是存储为BigInteger的大整数。

2个回答

3
Java提供了Random类的一个子类,即SecureRandom类。描述中包括:

该类提供了一个加密强度的随机数生成器(RNG)。许多实现形式是伪随机数生成器(PRNG),这意味着它们使用确定性算法从真随机种子产生伪随机序列。其他实现可能会产生真随机数,而另一些可能会同时使用两种技术。

Java仅提供了一个实现,即SHA1PRNG函数,它被详细说明为伪随机数生成(PRNG)算法:
这个实现遵循IEEE P1363标准,附录G.7:“源位的扩展”,并使用SHA-1作为PRNG的基础。它计算SHA-1哈希值,该哈希值由一个真随机种子值和一个64位计数器连接而成,该计数器每次操作递增1。从160位的SHA-1输出中,只使用了64位。
需要注意的是,OpenSSL的bn_rand_range函数也被认为使用伪随机数生成(PRNG)算法,尽管我找不到有关该函数实现了什么算法的详细信息。
因为SecureRandom是Random类的子类,所以SecureRandom对象可以使用Random的所有方法,包括nextInt(int n)方法。nextInt方法提供:
返回在此随机数生成器序列中绘制的介于0(含)和指定值(不含)之间的伪随机、均匀分布的int值。
因此,要在(0,100]范围内生成一个密码强的伪随机数,您可以使用以下代码:
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));
    }
}

我已经在我的Java实现中使用了SecureRandom来实现bn_rand_range。问题是,是否有一个函数的实现类似于bn_rand_range,而不是bn_rand。 - diedthreetimes
我已经更新了答案,展示出了模仿bn_rand_range的代码。你提到要找一个介于0和X之间的数字,所以我只使用了nextInt。如果你想要一个介于X和Y之间的范围,你可以使用random.nextInt(Y-X)+X - amccormack
抱歉,我忘了提到X不是int类型,而是BigInteger类型。否则你的方法正是我所寻找的。 - diedthreetimes

1
据我所知,这个功能并没有提供。但是你可以很容易地自己实现它。
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接