在 Java 中,我使用“SHA1PNRG”生成伪随机数。我不知道这个数字生成的内部工作。什么种子值最适合安全数字生成?我应该使用较小的数字作为种子还是使用较大的值作为种子?请善意给予适当的指导。
我的代码:
SecureRandom sr= SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
我sr.nextInt(int)
用于获取下一个值,并且seed
是一个长数据类型变量。
在 Java 中,我使用“SHA1PNRG”生成伪随机数。我不知道这个数字生成的内部工作。什么种子值最适合安全数字生成?我应该使用较小的数字作为种子还是使用较大的值作为种子?请善意给予适当的指导。
我的代码:
SecureRandom sr= SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
我sr.nextInt(int)
用于获取下一个值,并且seed
是一个长数据类型变量。
种子使用的数字无关紧要。重要的是每次启动程序时使用不同的种子编号。
PRNG 或伪随机数生成器通过对种子执行计算来工作。它使用该计算的输出作为下一个随机数的种子,依此类推。(这是一种简化,但它为您提供了正确的想法。)因此,如果您使用相同的种子,PRNG 将产生相同的数字序列。
典型的种子来自系统时间,或者来自用户的按键或鼠标移动,或者每次程序运行时可能不同的其他值。
当使用基于 SHA-1 的 Hash_DRBG(确定性随机位生成器)时,NIST SP800-90A建议种子长度为 440 位(即 55 个字节)。(那里也描述了该算法)。
但这不仅与种子的长度有关,还与它的熵(“随机性”)有关。如果你用一个 440 位的零字符串初始化 DRBG,尽管它的长度很长,但这将是一个糟糕的选择。
播种的目的是配置生成器的初始状态,这样攻击者将无法预测随机数的序列。请记住,所有过程都是确定性的,那么一旦有人知道生成器的状态,他就能够从那时起重现随机序列。
您可以使用 方法计算种子,该方法SecureRandom.generateSeed
依赖于当前操作系统提供的熵源(例如,OpenJDK 的 SeedGenerator在 Linux 上使用 /dev/random,在 Windows 上使用 MS CryptoAPI)。
SecureRandom sr= SecureRandom.getInstance("SHA1PRNG");
byte seed[] = random.generateSeed(55);
sr.setSeed(seed);
Maximin,如果您担心人们无法猜测种子(从而预测您的 PRNG 的输出),您应该使用实际上是随机的种子。例如,使用程序运行的时间是不安全的。
您不应该通过直接调用来绕过内部播种机制setSeed
。如果在调用 之前调用java.security.SecureRandom.setSeed(long)
or ,则绕过内部种子机制,仅使用提供的种子来生成随机数。java.security.SecureRandom.setSeed(byte[])
java.security.SecureRandom.nextBytes(byte[])
请参阅 Amit Thesi 几年前关于此主题的有用博客文章,网址为http://www.cigital.com/justice-league-blog/2009/08/14/proper-use-of-javas-securerandom/