【发布时间】:2012-04-05 11:42:25
【问题描述】:
我已经阅读了大量关于如何存储和比较输入的密码的文章,有些是旧的,有些是新的,但都不同。因此,我采用了我认为最好的选择并实施了以下方法。
请注意,我创建了自己的身份验证提供程序,我没有使用或继承标准 MS MembershipProvider(太臃肿)。这是针对不需要“超级安全”的轻量级站点,但我想遵循最佳实践。我只是想验证一下我没有做任何明显错误或打开安全漏洞的事情。另外,我查看了每个用户的密码加盐,但对于我的需求来说,它似乎过于复杂。这是一个有效的假设吗?
首先,我将以下 appSettings 键放入我的 web.config 中,该键由我的 configurationProvider 类返回。
<add key="PasswordEncryptionKey" value="qTnY9lf...40 more random characters here" />
这是我的代码,它公开验证用户并私下检查存储的密码与输入的内容以及编码密码保存时。我没有展示添加或更新密码的方法,因为它们使用相同的私有方法。
public bool Authenticate(string emailAddress, string password, bool setAuthCookie = false)
{
bool isAuthenticated = false;
var member = _memberRepository.Find(m => m.Email == emailAddress).SingleOrDefault();
if (member != null)
{
if (CheckPassword(password, member.Password))
{
isAuthenticated = true;
FormsAuthentication.SetAuthCookie(emailAddress, setAuthCookie);
}
}
return isAuthenticated;
}
private bool CheckPassword(string providedPassword, string storedPassword)
{
return EncodePassword(providedPassword) == storedPassword;
}
private string EncodePassword(string password)
{
var hash = new HMACSHA1
{
Key = Encoding.ASCII.GetBytes(_configurationProvider.PasswordEncryptionKey)
};
string encodedPassword = Convert.ToBase64String(hash.ComputeHash(Encoding.Unicode.GetBytes(password)));
return encodedPassword;
}
我唯一的规则是:
- 密码必须在数据库中异步加密,不能解密。
- 该方法对字典或其他攻击应该是合理安全的(我不是在开发一个 FDIC 保险网站,只是一个基本的 Intranet)
有了这个,我有什么明显的遗漏吗?
【问题讨论】:
-
如果您正在编写一个 Intranet 站点,为什么不使用 Windows 安全性?您滚动提供者的方法是一种很好的方法。 MS一号真的很臃肿。浏览您的代码或多或少是我为公共网站所做的,所以我认为您对所写的内容做得很好。请记住,一旦连接到网络,没有什么是真正安全的,您只是在设置层层障碍,希望攻击者感到无聊并离开。
-
对不起,彼得...我应该澄清得更好。它是一个基于 Internet 的站点,但适用于一个少于 100 名成员将登录的慈善团体。我应该使用“门户”这个词。所以它不会有大量流量,但我正在无偿开发它来练习我的技能,所以我只想知道最佳实践。
-
使用 PBKDF2 或 bcrypt 而不是自己滚动。
标签: c# asp.net-mvc encryption passwords