Random 使用加密安全的PRNG生成密码是否更安全?

Random 使用加密安全的PRNG生成密码是否更安全?,random,cryptography,Random,Cryptography,我们有一个脚本在我的工作中支持一个新的web服务器。该脚本包括创建多个帐户以运行服务、应用程序池等 我们需要为每个用户创建一个密码——即生成一个32个左右字符的ASCII字符串用作登录密码 对于是否应该使用加密安全的PRNG来完成这项工作,或者使用非加密安全的PRNG(带时间相关种子)是否足够,我们存在分歧(我们在.NET中工作,因此具体的决定是使用System.Random生成字符串和使用RNGCryptoServiceProvider——但是,这不是特定于语言的问题) 必须使用加密安全的随机

我们有一个脚本在我的工作中支持一个新的web服务器。该脚本包括创建多个帐户以运行服务、应用程序池等

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

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


必须使用加密安全的随机性来生成密码吗?或者,如果攻击者知道您生成随机密码的确切算法(例如,他掌握了您的代码),那么合理的种子纯PRNG就足够了吗?

理论上讲,他知道你在PRNG中植入了系统时间,然后他可以根据你的系统计时器的分辨率及时复制在每一时刻生成的密码,从而将他的暴力密码搜索减少了几个数量级

系统计时器本质上是零熵的,那么PRNG本身不是CS这一事实可能无关紧要,因为攻击者必须获取多个密码的数据才能破解它。但是,如果您已经在使用CSPRNG来植入PRNG,那么您最好首先使用它来创建密码

非CS PRNG速度快,适用于游戏模拟和Monte Carlo集成,但安全密码、nonce、密钥等应该真正使用安全算法


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

在许多情况下,攻击者可以轻松地恢复服务器的状态(非加密)从几个输出值生成随机数-不知道种子的任何信息。之后,预测所有未来和所有以前的随机数就变得微不足道了

这需要多少输出取决于算法。对于线性同余生成器,例如Java的
Java.util.Random
,可以从两个输出恢复状态。对于PHP和Python中使用的Mersenne Twister,需要获得624个输出。我不熟悉.NET,但我认为它是si相似的故事

根本不涉及复杂的数学。请自己看看:


结论:使用加密安全的随机数生成器处理与安全有关的任何事情。

您需要生成多少密码?如果您可以访问伪随机数生成器,那么为什么不使用它?32个字符太难记住了。您基本上是在要求您的用户编写密码我说的密码是用于自动服务的。没有人每天使用它们登录。它们被保存在一个安全的密钥存储中,没有人必须记住它们。问题只是关于生成这些密码的具体方法。你必须创建多少个密码?真的是麦汁吗h有争论吗?这真的只是一个有趣的问题,@EJP。我推荐我的答案来生成密码。我没有考虑过攻击者可以复制时间种子PRNG可以生成的所有潜在密码的情况。这是一个很好的观点。我想我想到的一点在你的第二段中已经提到了:that拥有N个密码的攻击者可能能够利用PRNG弱点猜测更多密码。在没有任何一种攻击的情况下,在假设的情况下,我在一个一次性过程中生成一个密码,任何攻击者都不知道,PRNG和CSPRNG生成的密码在质量上是否存在差异ty?我想我在上面的问题中所说的“质量”是指“可猜测性”——易于暴力。因此,如果我正确解释链接,如果一个人从
java.util.Random
(转换为8位ASCII字符或4位十六进制字符或类似字符)生成了一个由顺序整数组成的128位密码,密码空间实际上只有64位(最多),因为前两个32位输出将决定剩余的64位。可怕。@Peter更不用说,如果您使用同一个Random实例生成多个密码,其余的密码可以完全预测。此外,正如Lee Daniel Crocker指出的,种子也可以猜测,记住尝试1000000 diff不同的种子在计算机上运行得很快。@Peter在.net中更可怕的是,
系统。Random只有一个31位的种子。