c# - 使用 C# 保护用户密码 - Rfc2898DeriveBytes 与 SHA512

标签 c# security hash passwords salt

我一直在阅读有关保护数据库中用户密码的内容 ( https://crackstation.net/hashing-security.htm )。基本思想是可以理解的 - 生成随机盐,将其附加到密码并对密码进行哈希处理。

这就是我所做的(我没有在这里放置一些转换为字符串的方法):

RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create();
byte[] rndBytes = new byte[512];
randomNumberGenerator.GetBytes(rndBytes);
string salt = ToHexString(rndBytes);

var sha512Hasher = SHA512.Create();
string hashedPwd = ToHexString(sha512Hasher.ComputeHash(GetBytes(pwd + salt)))

根据这篇文章,这是安全的,但可以通过使用“ key 拉伸(stretch)”来更加安全,据我所知,“ key 拉伸(stretch)”是进行较慢的散列(使用参数)以使暴力破解密码变得更加困难。

这就是我所做的:

RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create();
byte[] salt = new byte[512];
randomNumberGenerator.GetBytes(salt);
Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(user.Password, salt, 1000);
byte[] hashBytes = k1.GetBytes(512);
string hash = ToHexString(hashBytes);

现在这是我的问题:

  1. SHA512Rfc2898DeriveBytes 有什么区别?哪个更安全?
  2. 我应该使用更小的盐和更多的迭代吗?它会让它更安全吗?
  3. 在 1000 次迭代中,它运行得非常快 - 应该慢到什么程度?半秒?一秒?这里的经验法则是什么?
  4. 在数据库中 - 我应该将字节数组转换为字符串并存储字符串,还是应该将字节数组存储在二进制数据字段中?

编辑(其他问题)

  • 如果我迭代 1000 次重新哈希 SHA512 - 是否能提供相同的安全性?
  • 最佳答案

    1. SHA512 和 Rfc2898DeriveBytes 有什么区别?

    SHA512 是一种加密哈希函数,而 Rfc2898DeriveBytes 是一种 key 派生函数。正如您已经写的,哈希函数太快并且太容易被暴力破解,这就是为什么我们需要具有成本因子的函数,例如 BCrypt、SCrypt、PBKDF2 或 Argon2。据我所知,Rfc2898DeriveBytes 使用带有 SHA1 的 HMAC 实现 PBKDF2。这回答了您的另一个问题,即迭代 SHA 的安全性低于 Rfc2898DeriveBytes。

  • 我应该使用更小的盐和更多的迭代吗?
  • 盐和成本因素不相关,并且有不同的用途。盐阻止了彩虹表的使用,迭代是暴力攻击的对策。更多信息可以从我的tutorial获取关于安全密码存储。所以不,不要让盐变短。

  • 应该慢到什么程度?
  • 当然,这取决于您的服务器和您对安全性的要求,速度越慢意味着越难暴力破解。经验法则是关于 50 milliseconds对于单个哈希。

  • 在数据库上 - 我应该将字节数组转换为字符串吗?
  • 这取决于你。字符串更容易处理备份、迁移和调试,而字节数组在数据库中需要的空间更少。也许您还应该看看BCrypt.Net ,它生成字符串作为输出,其中包含盐并且易于存储在单个数据库字段 [string] 中。

    关于c# - 使用 C# 保护用户密码 - Rfc2898DeriveBytes 与 SHA512,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41477844/

    相关文章:

    c# - Azure Active Directory WebApi - 服务器到服务器

    c# - 表达式 <Func<object, bool>> 作为属性

    c# - 未经授权的访问异常 StreamWriter

    c# - 所描述的数据模型的导航属性的实现

    ios - 钥匙串(keychain)中的密码 - 人们忘记了密码

    php - 如何仅允许 api 访问 android 或 ios 应用程序(laravel)?

    security - 唯一标识用户时使用客户端证书的哪些部分?

    email - 匿名比较两个电子邮件地址列表

    data-structures - 从字典中获取字谜列表

    database - 为R中数据框中的每一行数据创建哈希值