我总是听说 Crand()
不安全,但是您需要知道多少次调用才能预测下一个值(或至少减少可能性)?它们必须是顺序的吗?如果没有关于 rand() 的好信息,我会对任何其他广泛使用的随机数生成器感兴趣。
非加密随机数生成器有多不安全?
它通常取决于实现。在大多数情况下,您将看到线性同余发生器或线性反馈移位寄存器。
这些类型的生成器的一个常见问题是它们的周期通常很短,并且它们的数学形式意味着确定性生成。因此,您(通常)可以在几百次或更少的调用中打破它们。顺序结果确实使破解算法更容易,因为您可以通过这种方式建立更强的相关性,但它们不是必需的。
“新型”生成器的最大缺陷是种子不够大。例如,如果您有一个具有 32 位种子的生成器并且知道生成器的前 20 个值,那么暴力破解是微不足道的。只需为每个种子生成一个从 0 到 2^32 的序列,然后进行比较。您可以采用早期优化来大幅降低计算成本。
伪代码:
// the known values from the generator
byte[] knownValues = { 9, 55, 201, 50, 41, 111, 67, 44, 122, 66 };
for(seed = 0 to 2^32)
{
srand(seed);
bool found = true;
for(n = 0 to len(knownValues))
{
if(rand() != knownValues[n])
{
found = false;
break;
}
}
if(found == true)
{
print "Found potential seed: " + seed + "\n";
}
}
有了相当快的 RNG 和一些不错的硬件,这绝对是一个合理的攻击。
我建议您阅读以下内容以获得全面的解释:
实现rand()
因系统而异。我看过其中几个,安全性从可怕到绝对可怕。您绝对不想rand()
用于任何加密。
在某些系统上,一个输出rand()
足以恢复种子并预测所有未来的输出。在其他情况下,您需要 2 个输出rand()
。在某些系统上,如果您查看 的输出序列rand()&1
,您会发现您总是得到序列 0,1,0,1,0,1,...——换句话说,连续输出的最低有效位fromrand()
在 0 和 1 之间交替(即,输出rand()
在奇数和偶数之间交替)。
它有多不安全?和你想象的一样不安全。
我不知道用于 rand() 的确切实现,所以我将回答一般情况。
一种流行的非密码随机生成器是线性同余生成器。这可以通过少于 10 次连续调用*来预测。
*:上限可能要低得多,但这是作为密码学入门课程的第一周作业给出的,其中说明了它们是多么容易被破解。
CSPRNG 是 PRNG 的一个子集。PRNG 只需要在统计上是随机的。CSPRNG 需要在统计上是随机的,并且能够抵御密码分析以确定过去或未来的值,即使在已知大量关于初始值和/或过去值的信息的情况下也是如此。
当您只需要一个统计上随机的值(如密码盐或随机用户 ID)时,所有 PRNG 都足够安全;但是,当使用统计随机值的系统需要承受密码分析(在密码学中使用)时,CSPRNG 是必要的。