salt需要随机来保护密码哈希吗?

C.J*_*.J. 8 security passwords rfc2898

我对安全性知之甚少(我需要找到基本的基本解释),并试图找到一种合理的方法来使用.Net将用户密码存储在数据库中.

这是我目前的解决方案:

private static byte[] HashPassword(string password)
{
   using (var deriveBytes = new Rfc2898DeriveBytes(password, 10))
   {
      byte[] salt = deriveBytes.Salt;
      byte[] key  = deriveBytes.GetBytes(20);

      return salt.Concat(key).ToArray();  //Return Salt+Key
   }
}
Run Code Online (Sandbox Code Playgroud)

我将HashPassword()的结果存储在数据库中.要检查用户的密码,我这样做:

var salt = //1st  10 bytes stored in the DB
var key  = //Next 20 bytes stored in the DB 
using (var deriveBytes = new Rfc2898DeriveBytes(password, salt))
{
   byte[] newKey = deriveBytes.GetBytes(20);

   if (newKey.SequenceEqual(key) == false)  //Check if keys match
   {
      return "No Match";
   }
   else { return "Passwords match"; }
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果盐需要随机存储在DB中,或者如果我可以生成一个10字节的盐并将其存储在我的代码中,并且始终使用相同的盐来保存自己将盐存储在数据库中存储密钥?

如果有人看到我正在做的任何其他问题,我会感激任何建议.

Eri*_*ert 29

我的问题是,如果盐需要随机存储在DB中,或者如果我可以生成一个10字节的盐并将其存储在我的代码中,并且始终使用相同的盐来保存自己将盐存储在数据库中存储密钥?

绝对不.

如果你甚至问这个问题,你根本不明白盐的目的.

盐的目的是使攻击者使用散列公共密码的预先计算表变得更加困难.如果盐总是相同,则攻击者只是预先计算一个带有该盐的哈希公共密码表.

让我说清楚一点.假设攻击者已经获得了您的密码数据库,并且在她闲暇时对所有存储的哈希值进行攻击,以计算出与哈希相对应的密码.如果每个盐都不同,则攻击者必须对数据库中的每个条目进行新的攻击.如果每个盐都相同,则攻击一个用户会攻击每个用户.

此外:假设您为每个用户使用相同的盐.假设两个用户拥有相同的密码.并且假设攻击者已获得密码数据库.攻击者现在知道哪两个用户具有相同的密码,因为他们具有相同的盐渍哈希,并且可以合理地假设这是数据库中最弱的密码.攻击者可以集中精力(无论可能是什么)特别攻击该用户.一旦她知道用户的密码,用户在其他系统上使用该用户名和弱密码的可能性很大,攻击者现在可以在没有密码文件的情况下妥协.

你想要了解安全性是件好事; 你正在尝试用你的理解水平写一个真正的密码系统是很糟糕的.如果这是一个必须保护真实用户的真实系统,请使用由专家构建的系统,或聘请您自己的专家.你将建立一个无法破解的系统,而不是一个攻击者无法破解的系统.

此外:你要求互联网上的陌生人寻求安全方面的帮助.陌生人,你不知道他们是否知道他们在说什么,或者只是在做什么.找一个真正的安全专家(那不是我 - 我是语义分析器的专家).构建安全系统是最困难的编程任务之一; 你需要专业的帮助.

有关基本密码身份验证方案的简要介绍,请参阅我的系列文章:

http://blogs.msdn.com/b/ericlippert/archive/tags/salt/

  • 如果您希望避免聘请专家,Microsoft已代表您这样做.使用[Membership](http://msdn.microsoft.com/en-us/library/yh26yfzy.aspx). (4认同)