【问题标题】:Hash algorithm SHA256, is my method secure? How do I add a salt value to make more secure哈希算法 SHA256,我的方法安全吗?如何添加盐值以使其更安全
【发布时间】:2016-09-26 17:11:19
【问题描述】:

我对密码学很陌生,想了解散列算法。

我有以下来源来创建密码的哈希版本,可以存储在我的数据库中。

    public static string hashPasswordGenerator(string password)
    {
        System.Security.Cryptography.SHA256Managed crypt = new System.Security.Cryptography.SHA256Managed();
        StringBuilder hash = new StringBuilder();
        byte[] cry = crypt.ComputeHash(Encoding.UTF8.GetBytes(password), 0, Encoding.UTF8.GetByteCount(password));
        return Convert.ToBase64String(cry);
    }

我的示例用户是User1,密码为Password1,这将返回GVE/3J2k+3KkoF62aRdUjTyQ/5TVQZ4fI2PuqJ3+4d0= 的哈希版本

我的问题是:

  1. 这安全吗?
  2. 我应该在里面加盐吗?如果是这样,有人可以显示 我举个简单的例子,因为我不太明白盐是怎么回事 生成以便每次都匹配密码?
  3. 如果有人有这个 hashPasswordGenerator 方法,他们可以对我的密码进行反向工程吗?

提前致谢。

【问题讨论】:

  • 在您的示例中,从未使用过 StringBuilder hash = new StringBuilder();
  • Is SHA-1 secure for password storage? 的可能重复项(SHA-256 和 SHA-1 没有根本区别)
  • 您永远不应该使用简单的散列函数来散列密码。您需要使用故意慢速散列函数,如 PBKDF2、bcrypt、scrypt 和 Argon2。查看更多:How to securely hash passwords?

标签: c# security hash cryptography sha256


【解决方案1】:

这样安全吗?

是的,不是的。问题应该是“这对我的要求是否足够安全?”,这是只有您可以回答的问题。

我应该在里面加盐吗?

是的,你应该这样做。

如果有人有这个 hashPasswordGenerator 方法,他们可以对我的密码进行反向工程吗?

不,他们不能。在最坏的情况下,它会为他们指出正确的暴力破解方向。

您的解决方案的问题在于它太容易被破解。

第一个问题显然是缺少盐值,这意味着如果 2 个用户使用相同的密码,他们将拥有相同的哈希值,这样更容易破坏多个帐户。

其次,SHA256 太快了,不擅长制作安全密码哈希。您应该使用 bcrypt 或类似的方法来控制轮数,以使哈希生成“慢”。您希望它变慢的原因是因为您的应用程序一次只需要生成一个哈希,因此如果计算生成一个 has 所需的时间是使用 SHA256 的 10000 倍,这没什么大不了的,但是黑客需要生成数十亿的哈希值。因此,让他花费 10000 倍的时间对他来说是一件大事。

【讨论】:

  • 非常感谢您的回答,我已按照建议添加迭代查看了 PBKDF2。不过,我仍然对盐感到困惑。如果用户可以得到密码,他们是否也不能得到盐?
  • @user3284707 是的,但它会大大减慢暴力攻击。
  • @user3284707 这篇维基百科文章有更多关于how 的详细信息(解释不能放在堆栈溢出评论中)。
【解决方案2】:

这安全吗?

如果您只是使用不加盐的 SHA2,则不是这样。 (不是说 SHA2 可以轻松反转)

我应该在里面加盐吗?

是的。

如果可以的话,谁能给我一个简单的例子

使用RNGCryptoServiceProvider:

RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
var salt = new byte[32];
rngCsp.GetBytes(salt); // this will fill the buffer with random values

因为我不太明白它是如何生成盐的,所以它每次都会匹配密码

您必须保存盐(每个密码必须是唯一的)以及散列(密码+盐)。

如果有人有这种hashPasswordGenerator 方法,他们可以对我的密码进行反向工程吗?

是的,如果它是字典密码并且您没有使用盐。否则不会(在可预见的将来),因为散列应该很难反转。

顺便说一句,您应该考虑使用PBKDF2 来满足您的密码散列需求,而不是尝试重新发明轮子,因为它具有可以减缓蛮力攻击(迭代次数)的工作因素。

【讨论】:

  • 非常感谢您的回答。好的,那么盐我应该如何存储它,在一个单独的字段中,或者在同一个字段中。 PBLDF2 上的示例有 Convert.ToBase64String(salt) + "|" + Convert.ToBase64String(hash) 那么这是一个管道分隔的字符串吗?
  • 您可以将其存储在单独的字段中,因为无需解析字符串即可更轻松地回读。
  • 那么这个盐值是否在被散列之前添加到密码中,这意味着两个相同的密码永远不会被相同的散列?所以要在输入密码时检查密码,我查找盐,添加到纯文本密码,然后散列并查看它们是否匹配?
  • 是的。就是这样。
猜你喜欢
  • 2019-03-13
  • 2013-04-26
  • 1970-01-01
  • 2019-09-03
  • 2022-12-01
  • 1970-01-01
  • 2019-07-17
  • 2016-10-22
  • 2010-09-28
相关资源
最近更新 更多