【问题标题】:When you really do need to store a password in a database what are best practices当您确实需要在数据库中存储密码时,最佳实践是什么
【发布时间】:2011-05-27 10:12:57
【问题描述】:

我有一个使用 HMAC 来验证签名请求的 Web 服务。在这种情况下,我的服务的每个调用者都有一个密钥(密码)。用户当然会获得该密钥,但我还需要将密钥存储在我的数据库中,以便我的服务可以验证每个传入请求的签名。

所以在这种情况下,我确实需要将密码以我可以检索和使用的形式存储在数据库中。我不能使用仅在数据库中存储密码的加盐哈希的最佳做法。

我可以加密密钥,但我需要将加密密钥存储在某个地方。对于安全的 RESTful Web 服务来说,这是一个相当常见的场景,因此亚马逊 (AWS) 和微软 (Azure) 等公司必须处理这个问题。

在这种情况下有哪些最佳做法?

【问题讨论】:

  • 存储加密密钥有什么问题?
  • 我最近写了一篇关于基本密码存储的博文:blog.brokenbytes.info/2010/12/passwords-beating-the-dead-horse
  • 我关于存储加密密钥的评论只是为了解决我需要以某种方式保护加密密钥的事实。有点像鸡蛋的东西。我想不出任何其他方法来处理它,所以问题就变成了如何保护加密密钥。
  • 是否可以使用用户密码的哈希来签署请求?然后,您可以只使用存储在数据库中的哈希值,并更符合最佳实践。
  • 这是可能的,但我不认为它有多大成就。在这种情况下,密码实际上只是一个随机的字节流。如果我散列它然后使用散列来签署请求,我仍然需要存储散列。如果受到损害,将允许某人伪造请求。它只是不能避免我需要访问调用者用来签署请求的相同字节数组的问题。

标签: database security passwords


【解决方案1】:

密码应该存储在数据库中的唯一时间是连接到某个其他系统时需要密码。如果只需要检查其他实体提供的凭据,则应存储密码的哈希值。

即使需要使用密码与另一方联系,如果您需要其他凭据才能执行此类访问(例如,有人登录您的系统,然后您代表他们登录另一个系统),这也是可取的在可行的情况下,存储使用所提供密码的哈希加密的外部密码(但与存储在数据库中的哈希不同!)。如果有多个凭据可用于登录您的服务器,请为远程密码存储一份单独的加密密钥副本,并使用每个可接受的凭据进行加密。

【讨论】:

  • 我不同意。我的场景显然是我需要原始密码来执行签名验证的情况。他们用密钥签署了一个请求,我需要执行相同的签名过程并比较两个哈希值。所以这是我不需要连接到其他系统的情况,但我确实需要存储密码。签名的非对称加密性能不够,所以我们必须使用共享密钥。
  • 如果您必须使用要求双方拥有相同凭据的协议,您可能会被卡住。一个特定的密码会只在一个地方使用,还是可以在多个地方使用?如果是后者(例如,如果密码是 ASCII 文本),则可以通过使用 ASCII 密码的加盐哈希而不是密码本身来提高安全性。入侵数据库的人可以破解客户端以接受预先散列的值,但该值只会破坏一个系统,而不是使用相同 ASCII 密码的所有系统。
【解决方案2】:

如果您确实需要密码(例如,为了连接到另一个系统),我建议您将密码放在远离其他信息的地方。可能是另一个数据库,文件系统上的加密文件等。如果有人获得了您的主数据库,则不能保证他们也会获得相关密码。

这可能很明显,但您希望使用另一个密钥对密码的位置进行加密(以降低以某种方式获得对主要数据源的访问权限的人也将获得对密码数据存储的访问权限)。

【讨论】:

    【解决方案3】:

    听起来您的方案的最佳做法是使用公钥加密

    【讨论】:

    • 一个有效点,但在这种情况下,签名的非对称加密性能不够。
    • @BrettRobi:如何使用非对称加密发送用于加密签名的对称加密密钥?这通常会解决性能问题。
    猜你喜欢
    • 2012-04-28
    • 2018-07-27
    • 2011-01-24
    • 2017-02-20
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    相关资源
    最近更新 更多