【问题标题】:Best way to store password in database [closed]在数据库中存储密码的最佳方法[关闭]
【发布时间】:2020-08-10 05:14:13
【问题描述】:

我正在做一个需要身份验证(用户名和密码)的项目

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

我正在使用 C# 并连接到 2008 express 服务器。谁能建议(尽可能多的示例)存储此类数据的最佳方式是什么?

P.S 如果可以提供充分的理由,我愿意不将这些信息存储在数据库中

【问题讨论】:

  • 无论你做什么,如果你使用加密,不要像之前的海报提到的那样将密钥存储在代码中。这只是糟糕的做法。
  • '如何正确设置密码?'是一个至关重要的问题。这是一个棘手的问题,错误会产生严重的后果(回想一下 Tesco 和 LinkedIn 发生的事情)。我认为这个问题应该在programmers.stackexchange.com重新打开
  • 最好坚持标准 - 请参阅 en.wikipedia.org/wiki/PBKDF2 您只需找到您的语言的实现
  • 这个问题在安全论坛中得到了广泛的回答:security.stackexchange.com/questions/211/…

标签: database security passwords


【解决方案1】:

如果您不需要能够反转哈希,我会使用 MD5/SHA1 密码。当用户登录时,您只需加密给定的密码并将其与哈希值进行比较。在这种情况下,哈希冲突几乎是不可能的,除非有人获得对数据库的访问权并看到他们已经发生冲突的哈希。

【讨论】:

  • 我不会使用 MD5 进行散列 - 它基本上已经坏了 mscs.dal.ca/~selinger/md5collision
  • 其实也没那么破。他们可以做的是为两个不同的文件找到相同的哈希值。他们不能做的是反转 MD5 并获得工作密码。
  • 嗯,那不也坏了吗?您只需输入另一个生成相同哈希的密码,就可以进入了。您不需要知道原始密码。解决这个问题的方法是在散列之前对密码加盐。
  • @mjuarez 如果您在使用 MD5 之前在密码中添加盐,则冲突无关紧要,因为您无法使用其他密码
【解决方案2】:

在您的场景中,您可以查看 asp.net 成员资格,将用户密码作为散列字符串存储在数据库中是一种很好的做法。您可以通过将散列后的传入密码与存储在数据库中的密码进行比较来验证用户身份。

一切都为此目的而构建,请查看asp.net membership

【讨论】:

    【解决方案3】:

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

    因此,尽管您正在考虑这是一件好事并且这是一个好问题,但实际上这是这些问题的重复(至少):

    为了进一步澄清加盐位,简单地散列密码并存储的危险在于,如果入侵者获得了您的数据库,他们仍然可以使用所谓的rainbow tables 来能够“解密”密码(至少那些出现在彩虹表中的密码)。为了解决这个问题,开发人员在密码中添加了salt,如果正确完成,彩虹攻击根本不可能进行。请注意,一个常见的误解是简单地将相同的唯一且长字符串添加到所有密码中;虽然这并不可怕,但最好为每个密码添加唯一的盐。 Read this for more.

    【讨论】:

    • 我的意思是将密码存储在数据库中,而不是存储在其他地方。断章取义这句话似乎我支持存储纯密码,如果您阅读其余内容,我显然不支持。
    • 不仅是我所说的,我还引导他阅读大量讨论盐等的帖子......
    • @Paolo Bergantino:你确定你的帖子没有错字吗?它说:“对于您将遇到的大多数情况(老实说,我想不出任何反例)将密码存储在数据库中是正确的做法。” ???这似乎与您的 cmets 矛盾
    • Paolo 所说的话自相矛盾。密码的加盐哈希不是密码。将密码的加盐哈希存储在数据库中并不是将密码存储在数据库中。答案的主体非常恰当,但它的第一句话极具误导性。
    • @Robert:这已经非常接近于一个琐碎的语义游戏,但我还是会修复它......
    【解决方案4】:

    作为密钥硬化的加盐哈希,使用安全算法,例如 sha-512。

    【讨论】:

    • 在我看来,您应该始终使用慢速算法(例如 Blowfish)来存储密码。这篇文章是一个更好的答案:security.stackexchange.com/questions/211/…。把它放在这里,因为这个页面仍然在搜索结果中显示很高。
    • 遵循这个关于密码存储的建议是非常错误的。
    【解决方案5】:

    最佳安全实践是根本不存储密码(甚至不加密),而是存储加密密码的加盐哈希(每个密码具有唯一的盐)。

    这样一来,(实际上)不可能检索明文密码。

    【讨论】:

    • Wayne,通过在计算哈希之前加盐,彩虹表被有效地击败,只要盐足够大。
    • @Wayne Hartman:不是这样。如果盐值暴露,那么您必须为该特定盐值生成一个新的彩虹表。彩虹表的要点是预先计算哈希值。没有人会为他的特定盐准备一张彩虹桌。
    【解决方案6】:

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

    散列: 通过强大的散列函数存储用户密码散列(单向加密)。 搜索“c# encrypt passwords”会给出大量示例。

    请参阅online SHA1 hash creator 了解散列函数产生的内容(但不要将 SHA1 用作散列函数,请使用更强大的东西,例如 SHA256)。

    现在,散列密码意味着您(和数据库窃贼)不应该能够将该散列反转回原始密码。

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

    当用户登录时,他们会将用户名和密码交给您(原始文本) 您只需使用相同的哈希码对输入的密码进行哈希处理即可获得存储的版本。

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

    额外功劳:

    问题:如果我有你的数据库,那我就不能像开膛手约翰这样的破解者开始制作散列,直到找到与你存储的散列密码匹配吗? (因为用户无论如何都会选择简短的字典词......这应该很容易)

    答案:是的……是的,他们可以。

    因此,您应该“加盐”您的密码。 见Wikipedia article on salt

    "How to hash data with salt" C# example(存档)

    【讨论】:

    • 不错的帖子,除了一件事:md5 和 sha1 都被破坏了。您可能应该使用更强大的算法,例如 SHA2 系列。
    • 谢谢保罗——你是对的。由于 SHA2 的使用与使用 MD5 和 SHA1 一样简单,请使用更强的哈希算法。
    • SHA-1 没有被破坏。但是要对 Bruce Schneier 进行过渡:走,不要跑,去 SHA-2。
    • “所以,你应该‘加盐’你的密码”...但是加盐通常与密码一起存储在数据库中,那么这有什么帮助呢?攻击者只需将盐添加到他正在测试的字典攻击短语中。除了不会泄露重复密码之外,还有什么更安全的方法?
    • @joej “你永远......真的......需要知道用户的密码” - 这是一个非常短视的假设。有许多类型的应用程序确实需要以可检索的方式存储密码。例如,一个应用程序需要使用存储的凭据频繁登录到另一个系统,由用户提供和更新。
    【解决方案7】:

    我可能有点跑题了,因为您确实提到了用户名和密码的必要性,我对这个问题的理解诚然不是最好的,但 OpenID 值得考虑吗?

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

    如果有问题的应用程序纯粹供内部使用,则可能不适合

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

    【讨论】:

    • 我同意 openID 让人们面临挑战,但对于这个应用程序,它是一家公司的内部数据库,我怀疑他们是否希望任何老人进来登录。这个应用程序也不需要网络访问才能正常工作,所以我不想要求它。
    【解决方案8】:

    我强烈推荐阅读文章Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes [死链接,copy at the Internet Archive] 和How To Safely Store A Password

    很多程序员,包括我自己,都认为他们了解安全性和散列。可悲的是,我们大多数人都没有。

    【讨论】:

    猜你喜欢
    • 2013-01-25
    • 2021-02-11
    • 2012-09-13
    • 2013-04-01
    • 2012-01-01
    相关资源
    最近更新 更多