SecureRandom 数中的算法

Posted

技术标签:

【中文标题】SecureRandom 数中的算法【英文标题】:Algorithm in SecureRandom number 【发布时间】:2012-03-27 16:07:24 【问题描述】:

我在我的 android 客户端和服务器(Servlet)中得到一个随机数。我在客户端和服务器中都使用相同的 SecureRandom 算法(“SHA1PRNG”)。我的种子值对两者都是相同的。但是我得到的输出数字在客户端和服务器中都是不同的。可能是什么原因?这是我的代码:

SecureRandom random = new SecureRandom();
try 
    random.getInstance("SHA1PRNG");
 catch (Exception e) 
    // ...

;
random.setSeed(1097327);
byte[] b1 = new byte[3];
random.nextBytes(b1);
long value = 0;
for (int i = 0; i < b1.length; i++) 
    value += (b1[i] & 0xff) << (8 * i);
    Toast.makeText(getApplicationContext(), Long.toString(value),
            Toast.LENGTH_LONG).show();

【问题讨论】:

【参考方案1】:

SecureRandom 的 javadoc 说:

许多 SecureRandom 实现都是伪随机的形式 数字生成器 (PRNG),这意味着它们使用确定性 算法从真正的随机种子产生伪随机序列。 其他实现可能会产生真正的随机数,还有其他的 可以结合使用这两种技术。

也许该算法使用另一个随机源来产生它的随机数。这样做不会违反 SecureRandom 类的合同。它甚至会更满足它,因为安全随机生成器的目标是生成随机数,而不是可预测的数字序列。

【讨论】:

我在 Android 中使用了安全随机数生成器,两次使用相同的种子实例,我得到了两次相同的随机数。当我在 Servlets 中做同样的事情时,我得到了两个相同种子的两个相等的随机数。但问题是 Android 中的随机数不等于 servlet 中的随机数 Android 平台上的实现和您的servlet 使用的JDK 上的实现可能略有不同。但我的观点仍然存在:在几个不同的平台上,使用一个按照合同应该产生尽可能安全随机的数字的类并不是一个好主意,以便在几个不同的平台上获得可预测的数字序列。尝试使用您自己的算法,根据合同,在给定种子的情况下生成可预测的序列,或者在一侧生成数字,并与另一侧共享。 好的。我会考虑的。非常感谢小伙子。你真棒【参考方案2】:

让我在 4 年后投入我的 2 美分。

SecureRandom 实际上是系统相关的,这意味着生成数据的方式是特定于操作系统的。操作系统本身提供了一个获取熵的接口(甚至可能是您刚刚移动鼠标的方式)。这就是你得到不同结果的原因。

【讨论】:

以上是关于SecureRandom 数中的算法的主要内容,如果未能解决你的问题,请参考以下文章

jdk java.security.SecureRandom 性能问题

java.security.SecureRandom源码分析 java.security.egd=file:/dev/./urandom

java.util.Random 和 java.security.SecureRandom 之间的区别

解惑:SecureRandom极慢

Java中的随机数生成器:Random,ThreadLocalRandom,SecureRandom

java.security.NoSuchAlgorithmException: SHA1PRNG SecureRandom not available