如何在SecureRandom中正确使用setSeed()方法生成RSA素数

时间:2014-12-04 05:11:01

标签: java random cryptography rsa

我想为RSA密钥生成生成两个素数。我认为为了增加两个素数'随机性,随机可以生成如下:

SecureRandom r = SecureRandom.getInstance("SHA1PRNG");
r.setSeed(1232);
p = BigInteger.probablePrime(1024, r);
q = BigInteger.probablePrime(1024, r);

我的问题是:您认为使用SecureRandom会增加pq随机性吗?如果是这样,我如何随机设置setSeed()的值而不是使其成为固定值(这里我选择了1232)?

1 个答案:

答案 0 :(得分:2)

正如CodesInChaos已经显示的那样,SUN提供程序的默认实现使用系统随机数生成器自动播种。由于Java本身没有(显式)熵源,它或多或少依赖于系统的种子。

在从SUN提供商的setSeed检索数据之前,不应该调用"SHA1PRNG"因为这会使您的RNG(随机数生成器)成为确定性RNG - 它只会 使用给定的种子而不是将种子添加到状态。换句话说,它将始终生成相同的伪随机位或值流。

setSeed的初始调用可能因提供商而异。有时它会将种子用作种子,但它也可以只将种子添加到当前状态。在以后的Android版本(4.2以后)中,种子刚刚添加到随机状态,因此"SHA1RNG"将保持完全随机。

生成随机数生成器的最佳方法可能只是

SecureRandom r = new SecureRandom();

让Java运行时找出最好的。

如果你想使用一个显式算法(但是,SUN / Oracle不明确),你可以使用:

SecureRandom r = SecureRandom.getInstance("SHA1PRNG");

与您的代码一样。如果您想添加熵,请使用:

// just used to make sure that the SecureRandom is seeded by the OS
r.nextBytes(new byte[8]);
r.setSeed(1232);

常数值或文字不包含很多(如果有的话)熵。通常的熵来源是当前时间(甚至更好,System.nanoTime()),鼠标移动等。


对于Java 8,有一个新方法getInstanceStrong(),其中包含以下描述:

  

返回使用securerandom.strongAlgorithms安全属性中指定的算法/提供程序选择的SecureRandom对象。

     

某些情况需要强大的随机值,例如在创建RSA公钥/私钥等高价值/长期密码时。为了帮助指导应用程序选择合适的强SecureRandom实现,Java发行版包含securerandom.strongAlgorithms安全属性中已知的强SecureRandom实现列表。

哪个应该用作构造函数调用的替代。请注意,这可能会返回阻止 RNG,即:RNG可能阻塞您的线程,直到有足够的熵可用。它也可能会耗尽您的操作系统熵池阻止其他应用程序,因此只能谨慎使用它。