在数据库中存储加密的用户名哈希

时间:2009-03-29 05:25:21

标签: database security

我目前正在为我正在组合的应用程序进行基本用户身份验证,而且我对安全性没有太多经验。

这就是说,我理解将(盐渍)密码哈希作为blob存储/存储在数据库中的做法(和必要性),而不是密码(加密或否)。我已经实现了这个。

通过腌制/散列用户名并将哈希值存储在数据库中,而不是明文(或加密)中的用户名,是否可以获得任何好处?令我感到震惊的是,这将使得确定哪些用户可以使用数据库进行身份验证来访问系统变得更加困难。

由于让某人难以破解用户帐户的密码至关重要,因此增加确定哪些用户可行的难度也不合理吗?

编辑:我使用的某些语言可能不是100%正确:随意纠正: - )

Edit2:我改变了我的第一个点,表示盐渍哈希 - 感谢大家指出我错过了这个: - )

Edit3:删除了表示我正在加密/解密密码的措辞。我正在使用盐渍哈希并将其存储在数据库中 - 感谢Scotty指出这一点。

6 个答案:

答案 0 :(得分:9)

这取决于上下文

评估您所服务的材料的敏感度非常重要。为了深入挖掘,我将提供一些用例。

场景1:社交网络应用

您所有用户的互动都发生在公众面前。他们的电子邮件地址将用作他们的用户名。用户名不被视为私有,因为他们的名字出现在他们的所有帖子中。其他用户可以搜索用户名和/或启用电子邮件邀请。

判决 - Hashing = Bad

场景2:电子商务网站

用户可能会也可能不会参与公共互动(例如评论,评论)。使用电子邮件地址作为用户名可能是一个坏主意,因为通过使用密码恢复,受感染的电子邮件帐户意味着您网站上的用户帐户被盗用。

这里有很多灰色区域,通常是为了“方便”而被利用。如果您的网站使用电子邮件作为用户名,则存储运送历史记录和信用卡号;受损的电子邮件可能意味着您的用户会遇到很多身份盗用问题。

在这种情况下,使用用户名的政策,用户的电子邮件地址可能是个好主意。散列电子邮件不会增加价值。

注意:我在看着你Amazon.com

判决:通行证!=良好做法

情景3:色情网站

将用户名设为化名,并将登录名设置为用户的电子邮件地址。他们可能会倾向于谈论内容,并且不一定希望他们的名字出现在谷歌的黑色网站上。

在这里假设最坏的情况。如果您的数据库被黑客攻击,那么暴露您的用户身份可能会造成无法弥补的伤害。不要以为这可能发生在你身上吗? Take a look at this article

他们的用户帐户不仅遭到入侵,而且密码曝光,但很多用户很有可能在他们的电子邮件帐户中使用相同的密码。现在,他们的信息将匿名发布在PasteBin上,供全世界查看。更糟糕的是,他们中的大多数人可能甚至都不知道这已经发生了。

通过简单地对用户名和密码进行哈希处理,他们就会为自己和用户节省很多麻烦。

结论:绝对哈希电子邮件地址,无论它是否用作用户名。

场景4:银行

不言而喻,银行/金融网站不应该花钱。

可以通过以下方式增加安全性:

  • 使用电子邮件地址以外的用户名
  • 通过要求数字和字母强制使用唯一的用户名
  • 哈希密码
  • 需要2点身份验证(如果用户的电子邮件密码被泄露)
  • 散列电子邮件地址
  • 等...

不应该花钱来保护您的用户,因为如果不这样做,就意味着您正以赌博为生。


<强>结论:

适用于所有网站的安全性没有严格的规则。在某些情况下,用户名是公开的,因此散列它不会增加任何价值。在其他情况下,不散列它可能会造成无法弥补的伤害。如果您最终开发了一个可以使用户名/电子邮件哈希变得有用的网站,那么这是一个很好的方法。

  1. 哈希用户名
  2. 为用户生成唯一的盐
  3. 使用salt
  4. 哈希密码
  5. 将密码与salt一起存储在数据库中
  6. 通过不用盐对用户名进行散列,可以避免鸡/蛋问题。除非您对所有用户名使用静态salt。

    请记住,通过阅读代码可以找到所有用户帐户的静态盐。一旦找到静态盐,当采用彩虹表攻击时,它基本上是无用的。如果您对密码加密,请生成动态salt并将其与用户凭据的其余部分一起存储在数据库中。

    如果您想要简单的硬/快速规则,请记住一些好的假设:

    • 假设您的数据库可能会在某个时候受到侵害
    • 假设您的源代码在某些时候会被泄露
    • 假设您的用户的电子邮件将在某个时候受到侵害
    • 假设您的用户愚蠢并使用与您的电子邮件相同的密码
    • 假设黑客是聪明/机智和财务驱动的。

    如果您选择存储敏感/私人数据,那么进行额外步骤可能会在将来为您节省公关/法律噩梦。

    更新:关于seed hashing just showed up on Coding Horror的有趣文章。

答案 1 :(得分:5)

简答:很可能没有。

答案很长:您的情况似乎缺少“因为......我的用户名是敏感的”这一问题引发了一个问题:“为什么?保护用户名的具体,可证明的问题是什么?解决?“

没有这个问题,你所描述的是与安全相关的开发(以及整个开发)的常见缺陷:提出一些想法来保护或混淆系统的某些部分,然后寻找原因使用它。与软件开发中的任何内容一样,除了明确的问题出现之外,您应该避免做任何其他事情,直到只能通过使用特定工具来解决。

额外提示(免费!): salt your password hashes。普通的哈希值为far less secure

答案 2 :(得分:3)

如果你腌制&amp;哈希用户名,你会留下一些鸡肉和鸡肉。鸡蛋问题。

如果你腌制&amp;哈希用户名,您如何在数据库中找到它?您需要查找用户的记录以找到用于散列用户名的盐...

答案 3 :(得分:1)

可能不是。可以这样想 - 用户名是应用程序确定用户尝试登录的帐户的方式。密码是应用程序确定用户是否实际被允许以该帐户登录的方式。实际上,这意味着您将使用用户名作为索引在帐户表中查找一行。通过加密用户名,您只需要更难找到正确的行。

但是,如果你使用相同的加密方案加密用户名和密码,它们几乎同样安全 - 如果你可以打破一个,你可以打破另一个。因此,加密两者都会使查找用户变得更加困难,但不会增加任何额外的安全性。

注意:在您的问题中,您谈到解密密码字段。你可能想让这个变得不可能(从字面上看)。大多数人使用某种单向散列函数加密他们的密码(MD5和SHA256很受欢迎),以及盐。 “单向”部分只是意味着一旦你通过该功能运行某些东西,你就无法使用你得到的东西来获得你的开始。但是,如果从相同的输入开始,您将始终获得相同的输出。盐是一个秘密,只有你的应用程序知道(有点像加密密钥),它会在通过单向散列运行之前添加到你正在加密的任何内容中。这使得无法做到匹配来自两个不同站点的两个加密密码(假设它们使用不同的盐)。

答案 4 :(得分:0)

您的用户以纯文本格式存储密码并不公平,因为每个有权访问您数据库的人都可以看到他们的密码。你应该使用盐渍哈希。

Salt_(cryptography)

答案 5 :(得分:0)

您永远无法通过单独查看系统的单个部分来正确评估系统的安全性。你在哪里存储密钥来解密密码?

有权访问数据库的人是否也可以访问存储加密密钥的位置?如果是这样的话,你只是通过加密密码来获得安全方面的微小改进,并且可能通过加密用户名来获得更多的东西。

如果解密密钥和使用它的程序比数据库更安全 - 这是非常不寻常的,通常数据库处于最安全的位置 - 那么加密用户名可能会有额外的好处。在暴力攻击中剥夺攻击者的有用信息。