2

我需要/想要获得用于密码生成的随机(嗯,不完全)数字。

我做什么:目前我正在使用SecureRandom生成它们。
我正在获取对象

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

然后像这样播种

sec.setSeed(seed);

目标:一种(最好是快速)创建随机数的方法,它在加密上至少与 SHA1PRNG SecureRandom 实现一样安全。这些在 JRE 和 Android 的不同版本上需要相同。

编辑:种子是从用户输入生成的。

问题SecureRandom.getInstance("SHA1PRNG", "SUN");它会像这样失败: java.security.NoSuchProviderException: SUN. 省略, "SUN"会产生随机数,但这些与默认(JRE 7) 数字不同。

问题:我怎样才能实现我的目标

您不希望它是可预测的:我想要,因为我需要可预测性,以便相同的先决条件产生相同的输出。如果它们不一样,那么很难做到 用户对应用程序的期望。

编辑:通过可预测我的意思是,当知道一个字节(或一百个)时,你不应该能够预测下一个字节,但是当你知道种子时,你应该能够预测第一个字节(以及所有其他字节)。也许另一个词是可重现的。

如果有人知道更直观的方法,请告诉我!

4

4 回答 4

1

我最终将 Sha1Prng 从太阳源中分离出来,这保证了所有版本的 Java 和 android 的可重复性。我需要删除一些重要的方法来确保与 android 的兼容性,因为 android 无法访问 nio 类......

于 2013-04-09T18:46:48.710 回答
0

我建议使用UUID.randomUUID(),然后使用 getLeastSignificantBits() 和 getMostSignificantBits() 将其拆分为 long

于 2013-04-09T15:41:57.767 回答
0

如果你想要可预测的,它们不是随机的。这打破了您对“安全”的“目标”要求,并演变为两台服务器之间的简单共享秘密。

您可以通过使用素数的特征来获得看起来有点随机但可预测的东西,其中您通过从 I(某个特定整数)开始构建一组整数并添加第一个素数,然后与第二个素数取模。(事实上​​,第一个和第二个数字必须是相对质数——这意味着它们没有共同的质因数——不算 1,以防你称其为因数。

如果你重复加法和取模的过程,你会得到一组可以重复复制的数字,它们是按顺序排列的素数,你总是会得到相同的结果。

最后,如果第一个质数相对于第二个质数较大,则人类不容易预测该序列并且看起来有点随机。

例如,第一个素数 = 7,第二个素数 = 5(请注意,这显示了它是如何工作的,但在现实生活中没有用)

从 2 开始。加 7 得到 9。模 5 得到 4。4 加 7 = 11。模 5 = 1。

序列是 2、4、1、3、0,然后重复。

现在在现实生活中生成看似随机的数字。相对质数是 91193 和 65536。(我选择了第二个,因为它是 2 的幂,所以所有模值都可以放入 16 位。)

int first = 91193;
int modByLogicalAnd = 0xFFFF;

int nonRandomNumber = 2345; // Use something else
for (int i = 0; i < 1000 ; ++i) {
    nonRandomNumber += first;
    nonRandomNumber &= modByLogicalAnd;
    // print it here
}

每次迭代都会生成 2 个字节的随机数。如果您需要更大的随机“字符串”,您可以将其中几个打包到缓冲区中。

而且它们是可重复的。你的用户可以选择起点,你可以使用任何你想要的素数(或者,事实上,任何没有 2 作为因子的数字)。

顺便说一句- 使用 2 的幂作为第二个数字使其更可预测。

于 2013-04-09T15:56:27.423 回答
0

忽略使用某些物理输入(随机时钟位、电噪声等)的 RNG,所有软件 RNG 在相同的起始条件下都是可预测的。毕竟,它们是(希望)确定性的计算机程序。

有一些算法故意包含物理输入(例如,通过偶尔对计算机时钟进行采样)以试图防止可预测性,但这些是(据我所知)例外。

因此,任何“常规”RNG,给定相同的种子并按照相同的规范实现,都应该产生相同的“随机”数字序列。(这就是为什么计算机 RNG 更恰当地称为“伪随机数生成器”的原因。)

RNG 可以用以前使用的种子播种并复制“已知”数字序列这一事实并不会使 RNG 的安全性低于以某种方式阻止你播种的 RNG(尽管它可能不如间隔重新播种的花哨算法)。这样做的能力——一次又一次地重现相同的序列不仅在测试中非常有用,它在加密和其他安全应用中也有一些“现实生活”的应用。(事实上​​,加密算法本质上只是一个可重现的随机数生成器。)

于 2013-04-09T16:18:34.297 回答