2

我们有一个脚本可以在我的工作中建立一个新的 Web 服务器。该脚本涉及创建多个帐户来运行服务、应用程序池等。

我们需要为这些用户中的每一个创建一个密码——即生成一个 32 左右字符的 ASCII 字符串用作登录密码。

对于是否应该使用加密安全的 PRNG 来完成这项工作,或者使用非加密安全的 PRNG(具有时间相关的种子)是否足够(我们在 .NET 中工作,所以具体的决定),我们存在分歧是在System.Random使用 a 和使用 a生成字符串之间RNGCryptoServiceProvider——但是,这不是特定于语言的问题)。

必须使用加密安全的随机性来生成密码,还是明智地播种的普通 PRNG 就足够了?

4

2 回答 2

3

In many cases, an attacker can easily recover the state of a (non-cryptographic) random number generator from a few output values – without knowing anything about the seed. After that, it's trivial to predict all future and all previous random numbers.

How many outputs are required for this depends on the algorithm. In the case of a linear congruential generator, such as Java's java.util.Random, the state can be recovered from two outputs. For Mersenne Twister, used in PHP and Python among others, you need to obtain 624 outputs. I'm not familiar with .NET, but I'd think it's a similar story.

There is no complex math involved at all. See for yourself:

Conclusion: Use a cryptographically secure random number generator for anything that has to do with security.

于 2013-08-29T05:32:31.857 回答
2

从理论上讲,如果攻击者知道您生成随机密码的确切算法(例如,他掌握了您的代码),并且他知道您在 PRNG 中植入了系统时间,那么他可以及时重现每个瞬间生成的密码以无论您的系统计时器具有何种分辨率,都可以将他的蛮力密码搜索减少几个数量级。

系统计时器基本上具有零熵。如果您使用 /dev/random(在 Linux/OSX 上)或 CryptGenRandom(Windows)之类的东西为 RNG 播种,那么 PRNG 本身不是 CS 的事实可能并不重要,因为攻击者必须获得多个密码的价值数据能够破解它。但是,如果您已经在使用 CSPRNG 来播种 PRNG,那么您不妨一开始就使用它来创建密码。

非 CS PRNG 速度很快,非常适合游戏模拟和蒙特卡洛集成等事情,但安全密码、随机数、密钥等应该真正使用安全算法。

也就是说,与往常一样,安全性不是一个“是/否”的问题——它始终是成本/收益问题。正确的选择始终取决于您所保护的内容的价值、保护它的努力成本、可能的攻击者、失败的成本等等,因此没有针对每种情况的单一正确选择。

于 2013-08-28T23:41:50.427 回答