如何在ASP.Net应用程序中使用salting + hashing?

时间:2010-12-09 23:37:04

标签: c# sql-server hash salt

我正在从头开始建立一个项目,我想做Right Way™。我在网上看过有关哈希的内容,而且基本上是用64个字母的mumbo jumbo转密码,对吗?

腌制怎么样?

我的问题是:

  1. 如何使用C#散列字符串?
  2. MSSQL中的字段声明类型是什么?为nvarchar(64)?
  3. 什么是腌制,我需要将其保存在我的数据库中吗?
  4. 如果我打算让人们使用Facebook Connect,我是否需要担心创建哈希/盐?
  5. 首选代码示例。谢谢!

4 个答案:

答案 0 :(得分:1)

我将跳过问题1,因为我不是C#人。

问题3:

Salting在散列之前将一串随机数据添加到密码中。盐是必不可少的,因为没有它们,攻击者可能会预先生成rainbow table已知的密码哈希值。 Salting意味着彩虹表不能预先构建,这意味着每个密码必须单独强制使用。

为每个密码生成新的盐非常重要。

Salt值不是保密的,可以与数据库中的哈希密码一起存储。

用于生成和检查密码的伪代码如下:

generatePassword(String user, String password) {
    String salt = generateRandomSalt();
    String salted = salt + password;
    String hash = hexEncode(hash(salted));
    store(user, hash, salt);
}

checkPassword(String user, String testPassword) {
    String salt = lookupSalt(user);
    String salted = salt + testPassword;
    String testHash = hexEncode(hash(salted));
    return testHash.equals(lookupHash(user));
}

问题2:

数据库字段的长度取决于哈希算法。 SHA1生成160位输出,如果是十六进制编码,则为40个字符。一个好的经验法则是使用与哈希输出大小相同的盐,因此您将有两个40个字符的列:一个用于salt,另一个用于哈希。

问题4:

不知道Facebook Connect如何运作,抱歉。我希望其他两个答案都有帮助。

答案 1 :(得分:1)

1)代码

   public static string HashStringSha1(string plainText, string salt)
        {
            using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
            {
                byte[] bb = sha1.ComputeHash(Encoding.UTF8.GetBytes(salt + plainText + plainText));
                return Convert.ToBase64String(bb);
            }
        }

2)在SQLserver varchar中存储base64字符串

3)使用哈希将盐存储在不同的字段中。盐作为纯文本。

4)不确定你的意思。如果您使用OpenId,则无需存储密码。

答案 2 :(得分:0)

哈希& salt用于保证用户密码的安全。 MD5哈希是最常用的算法。散列函数是不可逆的 - >你无法从哈希中获取密码,但有人想到了 - 嘿!让我们生成一个包含示例密码及其哈希的表,然后对其进行排序并执行简单查找以检查密码。这就是为什么引入salt的原因 - 将salt添加到用户密码然后进行哈希处理。 Salt是随机生成的,因此应该保存在每个哈希的db中。

有关实施的详细信息,我建议您查看nopCommerce等实时示例,它是开源电子商务解决方案。 http://www.nopcommerce.com

(这个非常有用,因为它实现了一个自定义成员资格提供程序,它利用了salt& hash的思想)

答案 3 :(得分:0)

如何使用C#散列字符串?

看看这里: http://support.microsoft.com/kb/307020

MSSQL中的字段声明类型是什么?为nvarchar(64)?

是二进制数据。您可能希望将其格式化为字符串,但那是“额外的工作”

什么是腌制,我需要将其保存在我的数据库中的某个位置吗?

每个条目都应该使用一种独特的盐。盐在那里使得无法知道是否使用了相同密码的2倍。通常一个板条是由两个组件构成的......一个“共享秘密”(需要合理复杂,因此它可以击败查找列表)和一个独特的部分(例如DB中用户的ID值或其他东西。 ...只需确保“共享”+“唯一”+密码是唯一的

如果我打算让人们使用Facebook Connect,我是否需要担心创建哈希/盐?

如果您可以使用第三方API,那么您不必关心哈希盐析。只要您不保存密码,就不需要哈希。散列是单向函数,因此没有“好”的方式(提示:彩虹表)来重建原始密码。如果你让facebook处理身份验证,你不必担心所有的基础管道,因为你不存储密码。

如果您希望某些信息如此安全,即使是窃取您的数据库的人也无法访问它,也会使用哈希。顺便说一句:这包括你自己......没有办法重新创建原始密码...