【问题标题】:Replacing plain text password for app替换应用程序的纯文本密码
【发布时间】:2010-09-08 17:03:40
【问题描述】:

我们目前正在为我们拥有的网络应用程序存储纯文本密码。

我一直提倡使用密码散列,但另一位开发人员说这会不太安全——更多的密码可以匹配散列,字典/散列攻击会更快。

这个论点有道理吗?

【问题讨论】:

    标签: passwords


    【解决方案1】:

    绝对没有理由在网络应用程序上保留纯文本密码。使用带有盐值的标准哈希算法(SHA-1,而不是 MD5!),这样彩虹攻击就不可能了。

    【讨论】:

    • md5 完全不适合密码哈希
    【解决方案2】:

    希望您原谅我插入了我在此编写的解决方案,在传输密码之前使用客户端 JavaScript 对密码进行哈希处理:http://blog.asgeirnilsen.com/2005/11/password-authentication-without.html

    【讨论】:

      【解决方案3】:

      关于程序员伪装成密码学家有句老话:)

      Jeff Atwood 有一篇关于这个主题的好帖子:You're Probably Storing Passwords Incorrectly

      为了更广泛地回答,我同意以上所有观点,因为多个密码匹配相同的哈希,哈希使得 理论上 更容易获取用户的密码。然而, 与访问您的数据库的人相比,这种情况发生的可能性要小得多。

      【讨论】:

        【解决方案4】:

        绝对没有。但这没关系。我之前也发过类似的回复:

        不幸的是,人们,甚至是程序员,都太情绪化了,不容易被争论所左右。一旦他投资于他的职位(而且,如果你在这里发帖,他就是)你不可能仅用事实说服他。你需要做的是转换举证责任。你需要让他出去寻找他希望能说服你的数据,并在这样做的过程中了解真相。不幸的是,他有现状的好处,所以你有一条艰难的道路。

        【讨论】:

        • 很好理解——这确实是 OP 同事的情绪反应。解决温暖的模糊问题可能比硬逻辑和指标更有效率。也许将散列算法的选择推给同事,以便他们更愿意接受正确的解决方案?
        • 你有一个很好的观点。我没有在问题中提到,但这是他的代码——他以这种方式实现了它。它现在是我的代码,所以我可以单方面更改它,但我更愿意让他挽回面子/同意,以防我需要进一步帮助理解代码......
        【解决方案5】:

        没有什么比存储纯文本密码更安全的了。如果您使用的是不错的哈希算法(至少 SHA-256,但即使 SHA-1 也比没有好),那么是的,冲突是可能的,但没关系,因为给定哈希,不可能*计算出什么字符串散列到它。如果您使用密码对用户名进行哈希处理,那么这种可能性也会消失。

        * - 技术上并非不可能,但“计算上不可行”

        如果用户名是“graeme”,密码是“stackoverflow”,则创建一个字符串“graeme-stackoverflow-1234”,其中 1234 是一个随机数,然后对其进行哈希处理并存储“hashoutput 1234”在数据库中。在验证密码时,获取用户名、提供的密码和存储值末尾的数字(哈希具有固定长度,因此您始终可以这样做)并将它们散列在一起,并将其与散列进行比较部分存储值。

        【讨论】:

          【解决方案6】:

          如果你不加盐你的密码,你怀疑彩虹表攻击(预编译的字典具有给定哈希的有效输入)

          如果您以明文形式存储密码,其他开发人员应该停止谈论安全性并开始阅读有关安全性的内容。

          冲突是可能的,但对于密码应用程序来说通常不是一个大问题(它们主要是在使用哈希值作为验证文件完整性的方式的领域中的问题)。

          所以:对您的密码进行加盐(通过在密码右侧添加加盐*)并使用良好的散列算法,例如 SHA-1,或者最好是 SHA-256 或 SHA-512。

          PS:关于哈希的更多细节here

          *我有点不确定 Salt 应该放在字符串的开头还是结尾。问题是,如果您有冲突(具有相同哈希的两个输入),将 Salt 添加到“错误”一侧不会更改生成的哈希。无论如何,Rainbow Tables 不会有大问题,只有碰撞

          【讨论】:

            【解决方案7】:

            我在工作场所遇到了同样的问题。为了让他相信散列更安全,我所做的就是编写一个 SQL 注入,它从我们网站的公共部分返回用户和密码列表。它立即升级为一个主要的安全问题:)

            为防止字典/哈希攻击,请务必针对每个用户唯一且静态的令牌进行哈希处理(用户名/加入日期/用户 GUID 效果很好)

            【讨论】:

              【解决方案8】:

              这取决于你要防御什么。如果是攻击者拉下您的数据库(或诱骗您的应用程序显示数据库),那么明文密码是无用的。有许多攻击依赖于说服应用程序泄露它的私有数据——SQL 注入、会话劫持等。通常最好不要保留数据,而是保留散列版本,这样坏人就不能轻易使用它.

              正如您的同事所建议的,这可以通过对字典运行相同的哈希算法并使用彩虹表提取信息来轻松解决。通常的解决方案是使用秘密盐加上额外的用户信息来使散列结果唯一——例如:

              String hashedPass=CryptUtils.MD5("alsdl;ksahglhkjfsdkjhkjhkfsdlsdf" + user.getCreateDate().toString() +  user.getPassword);
              

              只要你的盐是秘密的,或者你的攻击者不知道用户记录的确切创建日期,字典攻击就会失败——即使他们能够下拉密码字段。

              【讨论】:

              • 什么?如果攻击者拥有您的“用户”表,他将拥有用户的 CreationDate。如果 CreationDate 不在“用户”表中,应用程序将如何登录?使用每个用户独有的数据进行盐渍化是个好主意,但攻击者也可以访问它。这样做的重点是攻击者必须为每个用户创建单独的彩虹表。这就是慢散列算法的用武之地。
              • 盐不必保密,也不应该对每个用户都一样。然后,可以使用该盐生成彩虹表。相反,每个用户都应该有一个随机生成的盐。它不需要那么秘密。如果你愿意,你可以发布它。关键是整个彩虹攻击一次只能对最多一个用户有效。
              【解决方案9】:

              事实是,如果你散列一些东西,是的,会有冲突,所以两个不同的密码可能会解锁同一个帐户。

              但从实际的角度来看,这是一个糟糕的论点 - 一个好的散列函数(md5 或 sha1 就可以了)几乎可以保证对于所有有意义的字符串,尤其是短字符串,不会发生冲突。即使有,为一个帐户匹配两个密码也不是什么大问题 - 如果有人能够以足够快的速度随机猜出密码,以至于他们很可能能够进入,那么你就有更大的问题了。

              我认为以纯文本形式存储密码比密码匹配中的哈希冲突带来更大的安全风险。

              【讨论】:

              • @SLaks: md5,虽然被破坏了,但仍然比存储纯文本密码更好。
              【解决方案10】:

              来自Wikipedia

              一些计算机系统存储用户 用于比较的密码 用户登录尝试,作为明文。如果 攻击者可以访问这样的 内部密码存储,所有密码 所以所有用户帐户都将是 妥协。如果某些用户使用 相同的帐户密码 不同的系统,那些将是 也被妥协了。

              更安全的系统存储每个 密码中的密码 受保护的形式,所以访问 实际密码仍然是 对于获得的窥探者来说很难 对系统的内部访问,而 验证用户访问尝试 仍有可能。

              一种常见的方法只存储一个 明文的“散列”形式 密码。当用户输入 在这样的系统上,密码 密码处理软件运行 通过加密哈希 算法,如果哈希值 从用户输入生成 匹配存储在 密码数据库,用户是 允许的访问。哈希值为 通过应用密码创建 散列函数到一个字符串组成 提交的密码和, 通常,另一个值称为 盐。盐可以防止攻击者 建立一个哈希值列表 常用密码。 MD5 和 SHA1 是 常用的加密哈希 功能。

              您可以在该页面上阅读有关该主题的更多内容。在我看来,在我阅读和使用过的所有内容中,散列是一个更好的方案,除非您使用非常小的(

              【讨论】:

                【解决方案11】:

                更多密码可以匹配哈希,字典/哈希攻击会更快。

                是和不是。使用现代散列算法,比如 SHA 变体,这个论点会变得非常非常周到。如果暴力攻击只需要 352 年而不是 467 年,你真的需要担心吗? (那里的轶事笑话。)获得的价值(没有以纯文本形式存储在系统上的密码)远远超过了您同事的关注。

                【讨论】:

                  【解决方案12】:

                  理论上,是的。密码可以比散列更长(更多信息),因此存在散列冲突的可能性。然而,大多数攻击都是基于字典的,碰撞的概率比成功的直接匹配要小得多。

                  【讨论】:

                    【解决方案13】:

                    我不明白您的其他开发人员如何'更多密码可以匹配哈希'。

                    存在“散列攻击会更快”的论点,但前提是您没有在密码被散列时加盐。通常,散列函数允许您提供盐,这使得使用已知的散列表成为浪费时间。

                    就个人而言,我会说“不”。基于上述情况,以及如果您确实以某种方式获得了明文公开,那么加盐的散列值对于试图进入的人来说几乎没有价值。散列还提供了使所有密码“看起来”的好处长度相同。

                    即,如果散列任何字符串总是产生 20 个字符的散列,那么如果您只查看散列,您无法判断原始密码是 8 个字符还是 16 个字符。

                    【讨论】:

                      【解决方案14】:

                      我不是安全专家,但我有一种感觉,如果纯文本更安全,那么一开始就不会存在散列。

                      【讨论】:

                      • -1:散列的用途远不止密码。并且仅仅因为某些东西存在并不意味着它具有任何价值(尽管在这种情况下它是)。一个真正的解释会增加价值。
                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-04-11
                      • 2010-10-31
                      • 1970-01-01
                      • 2018-07-18
                      • 2021-10-06
                      • 2015-05-26
                      • 2016-07-30
                      相关资源
                      最近更新 更多