【问题标题】:Encrypting Emails, Hashing Passwords, and Storing them in DB?加密电子邮件、散列密码并将其存储在数据库中?
【发布时间】:2011-12-15 13:51:51
【问题描述】:

首先,我对加密和散列的理解:

  1. 加密 - 可以解密
  2. 散列 - 不能取消散列

在构建 Web 应用程序时,我应该:

  1. 使用加密密钥加密电子邮件地址(将用于登录)。很高兴能够解密电子邮件地址以供以后使用(例如向用户发送电子邮件)
  2. 用盐对密码进行哈希处理。没有人应该能够看到用户的密码,所以散列(因为它是单向的)很好。

如果以上2点是对的,我应该把加密密钥和盐存放在哪里?

如果我将它存储在数据库中,那么如果数据库受到损害,这似乎有点毫无意义。不过,好处是我可以为每个用户分配一个唯一的加密密钥和盐。

我应该将加密密钥和盐存储在我的应用程序配置中吗?如果数据库被泄露,至少加密密钥和盐也不会被泄露(希望如此)。问题在于,这可能意味着每个人都共享相同的加密密钥和盐。

有什么建议?

【问题讨论】:

标签: php mysql security web-applications


【解决方案1】:

如果您完全加密电子邮件,则需要使用普通的盐/密钥。否则,您将如何通过数据库中的电子邮件地址选择用户来检查哈希密码是否正确?您不能每次都解密每个电子邮件地址。

总的来说,我认为加密电子邮件地址没有什么好处。如果需要,可以使用 MySQL 数据库加密,但不要在应用程序级别担心这一点。

散列密码的盐应该/需要是唯一的并且可以存储在数据库中,实际上它可以是散列本身的一部分。请参阅http://www.openwall.com/phpass/ 以获得良好的实现。

【讨论】:

  • 电子邮件加密不必使用普通的盐/密钥。重要的是您知道解密时间的盐/密钥是什么。加密电子邮件地址允许您在不损害人们的电子邮件地址的情况下公开您的数据库,就像 SO 所做的那样:data.stackexchange.com/*/query/new
  • 好的,所以你的数据库中有一堆伪随机噪声。用户foo@example.com 想登录。你做什么?当然,有一些方法可以做到这一点,例如使用电子邮件地址本身作为其自身的关键,但它仍然更加复杂,收效甚微。以 SO 的方式公开数据库并不意味着电子邮件地址是加密的,它只是意味着它没有在公共界面中公开。
  • 如果数据库被入侵,难道没有好处吗?如果电子邮件地址本身被加密不是更好吗?
  • 由于电子邮件地址需要可解密,因此您的服务器能够对其进行解密。如果您的数据库受到威胁,那么大多数情况下您的服务器也是如此。它只会在数据库遭到破坏但攻击者无法查看您的应用程序文件的情况下增加好处,这在 IMO 中是相当罕见的(但同样,您可能想就此向更多偏执的安全专家询问)。
  • @deceze - 你要求更多偏执的意见,也许我可以在这里提供帮助:-) 有许多攻击允许在数据库上执行查询,而无需在服务器上拥有管理员权限。未加密的电子邮件地址将成为一个有趣的目标。此外,db-server 和 web-server 通常位于不同的计算机上,控制 db-server 就足以获得未加密的电子邮件地址。
【解决方案2】:

盐应该是每个用户的,并且确实可以在数据库中;因此,盐的意义在于,拥有您数据库副本的人无法一次破解所有密码,而是分别破解。

至于加密密钥,这是一个更难的问题——绝对不要将它存储在数据库中;如果您的平台提供任何类型的受保护存储,您可能想要使用它。参见例如这个有用的答案:What's the best method to use / store encryption keys in MySQL

【讨论】:

    【解决方案3】:

    你的理解对我来说似乎是正确的。

    密码:只应存储密码的哈希值以及用户特定的盐值。盐可以明文存储,盐的原因是,攻击者不能为所有用户使用一个彩虹表(构建彩虹表很昂贵)。推荐使用hash_hmac()函数。

    EMail:我认为加密这些地址是个好主意,但是无论你怎么做,如果攻击者控制了服务器,他就能够恢复这些地址。我会将密钥放在一个单独的目录中,该目录位于 Web 根目录之外(不能直接从 Web 访问)。不要把它写在不需要解释就可以交付的文件中,扩展名 *.php 比 *.inc 好。如果您无权访问此类目录,请至少创建一个并使用 .htaccess Deny from all 保护它。

    如果您需要在数据库中查找电子邮件地址,您可以另外存储一个哈希,这允许搜索不区分大小写(先转为小写,然后生成哈希)。

    【讨论】:

    • 您能否详细说明“如果您需要在数据库中查找电子邮件地址,您可以另外存储一个哈希”?
    • 也许用户必须输入电子邮件和密码才能登录,然后您的应用程序必须找到用户。要查找用户,您需要在数据库中搜索此特定电子邮件地址。您可以在搜索之前加密电子邮件,但它会区分大小写。
    最近更新 更多