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

时间:2012-02-08 14:54:50

标签: 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
   }
}

我将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"; }

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

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

2 个答案:

答案 0 :(得分:29)

  

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

绝对没有。

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

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

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

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

您想了解安全性是件好事;你正在尝试用你的理解水平写一个真正的密码系统是很糟糕的。如果这是针对必须保护真实用户的真实系统,use a system built by experts聘请您自己的专家。您将创建一个无法破解的系统,而不是攻击者无法破解的系统。

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

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

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

答案 1 :(得分:1)

您不需要应用随机盐,但如果您这样做,您的密码将更加安全。显然,如果你确实应用了随机盐,那么你需要在数据库中存储散列密码,以便你可以检查提供的密码。

快速谷歌透露this post,这可能会帮助你。