在数据库中存储密码的最佳方法

Cra*_*893 451 database security passwords

我正在开发一个必须具有身份验证(用户名和密码)的项目

它还连接到数据库,所以我想我会在那里存储用户名和密码.但是,将密码仅仅放在数据库中的表中的文本字段似乎不是一个好主意.

我正在使用C#并连接到2008 Express服务器.任何人都可以(尽可能多的例子)建议存储此类数据的最佳方法是什么?

PS我很乐意这样的想法,如果可以提供一个很好的理由,这些信息不会存储在数据库中

Pao*_*ino 391

你是正确的,将密码存储在纯文本字段是一个可怕的想法.但是,就位置而言,对于您将要遇到的大多数情况(我真的想不出任何反例)在数据库中存储密码的表示是正确的事情.通过表示我的意思是你想要使用salt(对每个用户应该是不同的)和一​​个安全的单向算法来存储密码并存储,丢弃原始密码.然后,当您要验证密码时,您将对该值进行散列(使用相同的散列算法和salt)并将其与数据库中的散列值进行比较.

所以,虽然你正在思考这个并且这是一个好问题,但这实际上是这些问题的重复(至少):

为了进一步澄清盐渍位,简单地对密码进行哈希处理并存储的危险是,如果侵入者获得了数据库,他们仍然可以使用所谓的彩虹表来"解密"密码(至少显示在彩虹表中的那些).为了解决这个问题,开发人员为密码添加了一个,如果做得好,使彩虹攻击变得不可行.请注意,一个常见的误解是简单地为所有密码添加相同的唯一和长字符串; 虽然这并不可怕,但最好为每个密码添加独特的盐.阅读本文了解更多.

  • 我的意思是将密码存储在数据库中,而不是将密码存储在其他地方.将这句话脱离上下文使得我似乎支持存储普通密码,如果你阅读其余的我显然不会. (38认同)
  • @Robert:这已经危险地接近了一个小型的语义游戏,但我会修复它... (35认同)
  • 这不仅仅是我所说的,我还指导他过多讨论盐类的帖子...... (11认同)
  • 保罗所说的直接与自己相矛盾.密码的盐渍哈希不是密码.在数据库中存储密码的盐渍哈希不会将密码存储在数据库中.答案的主体是完全合适的,但它的第一句话极具误导性. (3认同)

joe*_*oej 51

背景 你永远......真的......需要知道用户的密码.您只想验证传入的用户是否知道帐户的密码.

哈希: 通过强哈希函数存储用户密码哈希(单向加密).搜索"c#encrypt passwords"可以提供大量示例.

请参阅在线SHA1哈希创建器以了解哈希函数产生的内容(但不要使用SHA1作为哈希函数,使用更强大的东西,如SHA256).

现在,散列密码意味着您(和数据库小偷)不应该将该散列反转回原始密码.

如何使用它: 但是,你说,我如何使用存储在数据库中的这个混合密码?

当用户登录时,他们会向您提供用户名和密码(在其原始文本中)您只需使用相同的哈希代码来对输入的密码进行哈希处理即可获得存储的版本.

因此,比较两个散列密码(用户名的数据库哈希值和键入的密码和哈希密码).您可以通过比较它们的哈希值来判断"他们输入的内容"是否与"原始用户为其密码输入的内容"相匹配.

额外信用:

问题:如果我有你的数据库,那么我不能像开膛手约翰那样拿一个黑客并开始哈希,直到找到你存储的哈希密码匹配?(因为用户选择简短的字典单词......应该很容易)

答:是的......是的,他们可以.

所以,你应该"加密"你的密码.请参阅有关salt维基百科文章

请参阅"如何使用salt散列数据"C#示例

  • 不错的帖子,除了一件事:md5和sha1都被打破了.您应该使用更强大的算法,例如SHA2系列. (14认同)
  • SHA-1尚未破解.但对于Bruce Schneier来说:走路,不要跑到SHA-2. (5认同)
  • @joej"你永远......真的......需要知道用户的密码" - 这是一个非常短视的假设.有许多类型的应用程序,其中以可以检索的方式存储密码是真正必要的.例如,需要经常登录到具有存储凭证的另一个系统的应用程序,由用户提供和更新. (4认同)
  • 谢谢保罗 - 你是对的.由于使用SHA2就像使用MD5和SHA1一样简单,请使用更强的哈希算法. (3认同)
  • "所以,你应该'加密'你的密码"......但盐通常与密码一起存储在数据库中,那么这有什么帮助呢?攻击者只需将盐添加到他正在测试的字典攻击短语中.除了它不会泄露重复的密码之外,它是如何更安全的? (2认同)
  • @FranciscoZarabozo 这两个系统的设计都很糟糕,因为当我的系统受到损害时,现在你系统上的我的用户也会受到损害。oAuth 等可以解决这个问题,但您需要“其他系统”来支持它。您永远不应该对用户密码进行可逆加密。 (2认同)

nil*_*amo 30

作为密钥加强的盐渍哈希,使用安全算法,如sha-512.

  • 在我看来,你应该总是使用慢速算法(例如Blowfish)来存储密码.这篇文章是一个更好的答案:https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords.只需将其放在此处,因为此页面在搜索结果中仍然显示为高. (5认同)
  • 遵循此密码存储建议将大错特错。 (2认同)

Mit*_*eat 26

最好的安全做法是根本不存储密码(甚至不加密),而是存储加密密码的盐渍哈希(每个密码使用唯一的盐).

这样(实际上)无法检索明文密码.

  • Wayne,通过在计算哈希值之前进行盐析,如果盐的尺寸足够大,则彩虹表会被有效地击败. (11认同)
  • @Wayne Hartman:不是这样.如果暴露了盐值,则必须为该特定盐值生成新的彩虹表.彩虹表的要点是预先计算哈希值.没有人会为他的特定盐提供彩虹表. (11认同)

zeb*_*box 10

我完全建议阅读足够的彩虹表:您需要了解的有关安全密码方案的内容 [死链接,在Internet存档上复制 ]以及如何安全地存储密码.

包括我自己在内的许多程序员认为他们理解安全性和散列.可悲的是,我们大多数人都没有.

  • 文章给出了404. (3认同)

Cri*_*urf 6

我可能稍微偏离主题,因为你提到了用户名和密码的需要,而我对这个问题的理解并不是最好的,但OpenID是值得考虑的吗?

如果您使用OpenID,那么如果我正确理解了技术并且用户可以使用他们已有的凭据,那么您根本不会最终存储任何凭据,从而无需创建特定于您的应用程序的新身份.

如果相关的应用程序纯粹是供内部使用,则可能不合适

RPX提供了一种将OpenID支持集成到应用程序中的简便方法.