我需要/想要获得用于密码生成的随机(好,不完全)数字。
我的工作:目前我正在使用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)数字不同。
问题:如何实现目标?
你不希望它是可预测的:我想要,因为我需要可预测性,以便相同的前提条件产生相同的输出。如果它们不相同,那么 hard 就可以完成用户对应用程序的期望。
如果有人知道更直观的方式,请告诉我!
答案 0 :(得分:1)
我最终将Sha1Prng与太阳光源隔离开来,这保证了所有Java和Android版本的可重复性。我需要删除一些重要的方法来确保与android的兼容性,因为android无法访问nio类......
答案 1 :(得分:0)
我建议使用UUID.randomUUID(),然后使用getLeastSignificantBits()和getMostSignificantBits()
将其拆分为long答案 2 :(得分:0)
如果你想要可预测,它们不是随机的。这打破了“安全”的“目标”要求,并将其转换为两个服务器之间的简单共享密钥。
你可以得到看起来有点随机的东西,但可以通过使用素数整数的特征来预测,你可以通过从I(某个特定的整数)开始构建一组整数并添加第一个素数,然后用第二个模数素数。 (事实上,第一和第二个数字只需要相对素数 - 意味着它们没有共同的素数因子 - 不计算1,以防你称之为因子。
如果你重复添加和执行模数的过程,你将得到一组你可以重复重现的数字,它们是按照集合中的任何成员,添加第一个素数并进行模数的意义排序的到第二个素数时,你总会得到相同的结果。
最后,如果第一个素数相对于第二个素数较大,则序列不易被人类预测,并且似乎是随机的。
例如,1st prime = 7,2nd prime = 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的数字作为因子)。
BTW - 使用2的幂作为第二个数字使其更具可预测性。
答案 3 :(得分:0)
在使用相同的起始条件的情况下,忽略使用某些物理输入(随机时钟位,电噪声等)的RNG,所有软件RNG都是可预测的。毕竟,它们是(希望)确定性的计算机程序。
有些算法故意包含物理输入(例如,通过偶尔对计算机时钟进行采样)以试图防止可预测性,但这些(据我所知)是例外。
因此,任何“常规”RNG,给定相同的种子并实施到相同的规范,应该产生相同的“随机”数字序列。 (这就是计算机RNG更恰当地称为“伪随机数字生成器”的原因。)
RNG可以使用以前使用过的种子播种并重现“已知”数字序列,这一事实并不能使RNG的安全性低于某种情况下无法以某种方式阻止它播种的情况(尽管它可能不如每隔一段时间自行重新设定的花式算法安全。并且这样做的能力 - 一次又一次地重现相同的序列不仅在测试中非常有用,它在加密和其他安全应用程序中具有一些“现实”应用程序。 (实际上,加密算法本质上只是一个可重现的随机数生成器。)