java 我应该播种 SecureRandom 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7608089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 20:40:25  来源:igfitidea点击:

Should I seed a SecureRandom?

javarandom

提问by Svish

Found the following code in our code base:

在我们的代码库中找到以下代码:

public static final int DEFAULT_LENGTH = 16;
private static SecureRandom SR;
static
{
   try
   {
      SecureRandom sd0 = new SecureRandom();
      SR = new SecureRandom(sd0.generateSeed(DEFAULT_LENGTH * 2));
   }
   catch (Exception e){}
}

Here a default SecureRandomis created, and then that is used to create a seed for another one which is the one that will be used later in the class. Is this really necessary? Is the second somehow better than the first because this is done?

这里SecureRandom创建了一个默认值,然后它用于为另一个将在课程中使用的种子创建种子。这真的有必要吗?第二个是否比第一个更好,因为这已经完成?

When the seed is generated for the second, the number of bytes is given, is this important? Could a SecureRandomseeded with a different amount of bytes than another potentially be better or worse? Should the number of bytes used to seed it somehow correspond to what it will be used for?

第二次生成种子的时候,给定了字节数,这个重要吗?SecureRandom与另一个不同字节数的种子是否可能更好或更差?用于播种的字节数是否应该以某种方式对应于它将用于什么?

If setSeed is not called, the first call to nextBytes will force the SecureRandom object to seed itself. This self-seeding will not occur if setSeed was previously called. - javadoc

如果未调用 setSeed,则对 nextBytes 的第一次调用将强制 SecureRandom 对象为自己设定种子。如果之前调用了 setSeed,则不会发生这种自播种。-文档

Is the self-seeding not good enough? Does it depend on what it's going to be used for?

自种还不够好?这取决于它的用途吗?



Note:For some context, it is used in class that creates random ids for stuff stored in a database.

注意:对于某些上下文,它用于为存储在数据库中的内容创建随机 ID 的类。

采纳答案by ddso

I think this is completely unneccessary, because as the Javadoc you quote clearly states: Default-constructed SecureRandominstances seed themselves. The person who wrote this probably didn't know that.

我认为这是完全没有必要的,因为正如您引用的 Javadoc 明确指出的那样:默认构造的SecureRandom实例会自行播种。写这篇文章的人可能不知道。

They might also actually decrease security by forcing a fixed seed length that could be less-than-ideal for the RNG implementation.

它们实际上也可能通过强制固定种子长度来降低安全性,这对于 RNG 实现来说可能不太理想。

Finally, assuming the snippet is posted unaltered, the silent exception swallowing isn't very good coding style either.

最后,假设代码片段没有改变,沉默的异常吞咽也不是很好的编码风格。

回答by alexbt

Avoid using the default algorithm which is the case when doing new SecureRandom();

避免使用默认算法,这样做时就是这种情况 new SecureRandom();

Instead do:

而是这样做:

SecureRandom.getInstance("SHA1PRNG", "SUN");

If someone changes the default algorithm (as stated by @Jules) you won't be impacted.

如果有人更改了默认算法(如@Jules 所述),您将不会受到影响。



Edited for Android:

为安卓编辑:

For android, take a look at :

对于安卓,看看:

On Android, we don't recommend specifying the provider. In general, any call to the Java Cryptography Extension (JCE) APIs specifying a provider should only be done if the provider is included in the application or if the application is able to deal with a possible ProviderNotFoundException.

在 Android 上,我们不建议指定提供程序。通常,只有在应用程序中包含提供程序或应用程序能够处理可能的 ProviderNotFoundException 时,才应执行对 Java Cryptography Extension (JCE) API 的任何调用以指定提供程序。

...

...

in Android N we are deprecating the implementation of the SHA1PRNG algorithm and the Cryptoprovider altogether

在 Android N 中,我们完全弃用了 SHA1PRNG 算法和加密提供程序的实现

回答by Jules

This is not only completely unnecessary, it may actually increase the predictability of the numbers generated by the SecureRandom object.

这不仅完全没有必要,而且实际上可能会增加 SecureRandom 对象生成的数字的可预测性。

A SecureRandom that does not have an explicit seed set will self-seed. It uses a highly random data source to perform this operation, and is quite secure. The first SecureRandom in your code sample will use such a seed.

没有明确种子集的 SecureRandom 将自我播种。它使用高度随机的数据源来执行此操作,并且非常安全。代码示例中的第一个 SecureRandom 将使用这样的种子。

The second is seeded from the first by producing 256 random bits. Assuming the system-default SHA1PRNG is used, this is good enough. It uses 160 bits of state, so 256 random bits will completely satisfy it's requirements. But assume now somebody decides this isn't enough, and switches the default to a SHA512PRNG (they can do this without even looking at your code by changing java's security properties). Now you're providing too few seed bits to it: only half as many as it needs.

第二个是通过产生 256 个随机位从第一个开始的。假设使用了系统默认的 SHA1PRNG,这就足够了。它使用 160 位状态,因此 256 位随机位将完全满足它的要求。但是假设现在有人认为这还不够,并将默认值切换为 SHA512PRNG(他们甚至可以通过更改 java 的安全属性来执行此操作,而无需查看您的代码)。现在你为它提供的种子太少了:只有它需要的一半。

Get rid of it, and just use the self-seeded object, unless you have a better source of seed data than the system has available.

摆脱它,只使用自种子对象,除非您有比系统可用的更好的种子数据源。

回答by HenriqueMS

Just an addendum to this answer. According to Google, if you are using this code in android you should definitely seed the SecureRandom using a high entropy source like /dev/urandom or /dev/random.

只是这个答案的附录。根据 Google 的说法,如果您在 android 中使用此代码,则绝对应该使用像 /dev/urandom 或 /dev/random 这样的高熵源为 SecureRandom 播种。

Even the post below is an year old now, perhaps this has already been corrected but I couldn't confirm if it was.

甚至下面的帖子现在已经有一年了,也许这已经得到纠正,但我无法确认是否正确。

https://plus.google.com/+AndroidDevelopers/posts/YxWzeNQMJS2

https://plus.google.com/+AndroidDevelopers/posts/YxWzeNQMJS2

EDIT:

编辑:

It seems that the default behavior of the class is now the one specified in the post so seeding is again deemed unnecessary:

似乎该类的默认行为现在是帖子中指定的行为,因此再次认为不需要播种:

http://developer.android.com/reference/java/security/SecureRandom.html

http://developer.android.com/reference/java/security/SecureRandom.html

回答by Sam Ginrich

Sad, that javadocdoes not say, what the minimum seed size "DEFAULT_LENGTH" is to reach the intended security level of algorithm design, not even for some default implementation. :(

可悲的是,javadoc没有说,最小种子大小“DEFAULT_LENGTH”是什么才能达到算法设计的预期安全级别,甚至对于某些默认实现也是如此。:(

Essentially security depends on true random; there is nothing like "an algorithm seeding itself without exterior data". Unless the inputs of a seed generator are revealed, it is not possible to certify any security level.

本质上,安全性取决于真正的随机性;没有什么比“没有外部数据的算法自己播种了”。除非种子生成器的输入被泄露,否则无法证明任何安全级别。

Providers of true random are 1.) https://www.random.org/2.) Tools as VeraCrypt derive white noise from mouse motion.

真正随机的提供者是 1.) https://www.random.org/2.) VeraCrypt 工具从鼠标运动中获得白噪声。

If your goal is real security, you will combine numbers from anonymous random generators with self-cerified white noise.

如果您的目标是真正的安全,您会将匿名随机生成器的数字与自我验证的白噪声相结合。