- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经阅读了大量关于如何存储和比较输入的密码的文章,有些是旧的,有些是新的,但都不同。因此,我采取了我认为最好的选择并实现了以下措施。
请注意,我创建了自己的身份验证提供程序,我既没有使用也没有继承自标准的 MS MembershipProvider(过于臃肿)。这是针对不需要“ super 安全”的轻量级站点,但我想遵循最佳实践。我只是想验证一下我没有做任何明显的错误或打开安全漏洞。此外,我查看了每个用户的密码加盐,但它似乎对我的需求来说过于复杂。这是一个有效的假设吗?
首先,我将以下 appSettings 键放入我的 web.config 中,它由我的 configurationProvider 类返回。
<add key="PasswordEncryptionKey" value="qTnY9lf...40 more random characters here" />
这是我的代码,它公开验证用户并私下检查存储的密码与输入的内容以及编码密码保存时。我没有显示添加或更新密码方法,因为它们使用相同的私有(private)方法。
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;
}
我唯一的规则是:
有了这个,我有什么明显的遗漏吗?
最佳答案
我相信你的方案已经足够了,但还可以再改进一点。
在我看来,您已经开始使用 app.config 文件中的 EncryptionKey 进行加盐方案。然而,为了获得最佳安全实践,通常人们对每个密码使用不同的盐,并将盐与哈希一起存储在数据库中。
class MyAuthClass {
private const int SaltSize = 40;
private ThreadLocal<HashAlgorithm> Hasher;
public MyAuthClass ()
{
// This is 'ThreadLocal' so your methods which use this are thread-safe.
Hasher = new ThreadLocal<HashAlgorithm>(
() => new HMACSHA256(Encoding.ASCII.GetBytes(_configurationProvider.PasswordEncryptionKey)
);
}
public User CreateUser(string email, string password) {
var rng = new RNGCryptoServiceProvider();
var pwBytes = Encoding.Unicode.GetBytes(password);
var salt = new byte[SaltSize];
rng.GetBytes(salt);
var hasher = Hasher.Value;
hasher.TransformBlock(salt, 0, SaltSize, salt, 0);
hasher.TransformFinalBlock(pwBytes, 0, pwBytes.Length);
var finalHash = hasher.Hash;
return new User { UserName = email, PasswordHash = finalHash, Salt = salt };
}
使用这样的方案,您的密码会变得更加复杂,因为如果攻击者碰巧获得了哈希值,他还必须在暴力攻击期间猜测盐值。
这与配置文件中的 EncodingKey 的原理相同,但更安全,因为每个散列都有自己的盐。检查输入的密码是类似的:
public bool IsPasswordCorrect(User u, string attempt)
{
var hasher = Hasher.Value;
var pwBytes = Encoding.Unicode.GetBytes(attempt);
hasher.TransformBlock(u.Salt, 0, u.Salt.Length, Salt, 0);
hasher.TransformFinalBlock(pwBytes, 0, pwBytes.Length);
// LINQ method that checks element equality.
return hasher.Hash.SequenceEqual(u.PasswordHash);
}
} // end MyAuthClass
当然,如果您更愿意将散列存储为字符串而不是字节数组,欢迎您这样做。
只需我的 2 美分!
关于c# - 我的 MVC3 密码处理是否足够,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9796419/
对于我的问题,我找不到更好的措辞。 在我的应用程序中的某个时刻,我设置了一些非常密集的动画。问题是,在高端设备上,动画运行流畅且赏心悦目。另一方面,我测试过的一台低端设备在制作动画时表现非常糟糕。 试
我正在修补 OTP 模块 ( yubico_pam ),并尝试访问管理员选择的控制标志(例如必需,足够, ETC)。 有什么想法吗?这是否可行(无需解析文件)? 最佳答案 无法在 API 中查询此信息
我有一些为 Linux 编写的 C 代码,依赖于套接字和 arpa/inet.h 以及 libusb.h,我想在 MinGW 下为 Windows 编译它。 (请注意,当前项目只有一个非常简单的 Ma
我是一名优秀的程序员,十分优秀!