下面的代码使用PRNG(伪随机数生成器)Random
类为初始临时密码生成密码字符,而不是应该使用的密码安全RNGCryptoServiceProvider
。< / p>
然而,它确实使用RNGCryptoServiceProvider
为PRNG生成种子,所以我认为这可能值某些,而不是根据当前时间播种使用PRNG时的典型做法是安全性不是问题。
我的问题是:为了破坏密码生成系统并猜测新用户的密码,这种攻击方法有多容易或多难?
// Generate 4 random bytes.
byte[] randomBytes = new byte[4];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(randomBytes);
// Convert 4 bytes into a 32-bit integer value.
int seed = (randomBytes[0] & 0x7f) << 24 | randomBytes[1] << 16 | randomBytes[2] << 8 | randomBytes[3];
// Now, this is real randomization.
Random random = new Random(seed);
然后代码继续使用random.Next()
生成填写密码字符串的字符。
免责声明:此代码不属于我的发明。不要因为它而责备我,也不提供如何解决它的建议。我知道如何解决它,我知道这很糟糕。不要浪费时间回复。任何有关此效果的评论或答案都将被标记为垃圾邮件。我只在我们的代码中找到它并且对它的“安全”属性感到好奇。
答案 0 :(得分:5)
PRNG功能的问题在于可预测性。能够根据以前的输出预测它的输出。避免使用Random
类的原因是,通过监视它的输出,可以开始预测未来的输出。
上面的代码可能是也可能不是问题。这归结为Random
类实例化的频率。如果您正在使用来自加密PRNG的种子创建一个新实例,并且只生成一个密码,那么您应该没问题。我之所以这么说是因为即使我从一个生成的密码中了解PRNG的状态,它也与未来生成的密码无关。
如果您正在使用此例程来初始化Random
的静态实例,那么您肯定有潜在的问题。假设某人使用此方法向电子邮件发送临时重置密码。攻击者可以重置自己的密码足够的时间来开始预测未来的密码。一旦他可以预测下一个密码,他只需为他希望妥协的帐户启动剩下的密码。已经知道通过电子邮件发送的密码,然后他就可以访问该帐户了。