【问题标题】:Securely storing credentials that can't be encrypted安全存储无法加密的凭据
【发布时间】:2013-11-19 15:46:59
【问题描述】:

我有一个客户正在运行来自多个帐户的信息聚合器。数据库需要将用户名和密码存储到其他网站,以便稍后脚本可以使用该方式登录这些网站以检索数据。

与其将它们存储为纯文本,我认为我们可以对它们进行哈希存储。显然,如果有人可以访问代码和数据库,他们仍然可以访问纯文本版本,但如果他们只有一个或另一个,则不能。

有更好的想法吗?

【问题讨论】:

  • 澄清一下,您是否控制对这些其他帐户的访问?我假设这是来自外部第三方帐户的聚合器(例如跨社交网站、银行等的凭据)
  • 我没有。一个虚假但简单的例子是一个网站,它允许用户从一个网站检查他们所有银行账户的余额。我们的网站要求他们提供所有银行帐户的用户名和密码,以便我们的脚本可以检查它们并向他们发送合并金额的短信。显然我们不想将这些凭证存储为纯文本,但我也不能加密它们,因为我们的自动化脚本也不能使用这些凭证。在这种情况下,隐藏数据的最好的方法是什么?
  • 哦,好吧,那我肯定喜欢 Ramon 的建议。然后,您至少已将每个用户锁定。

标签: database encryption passwords cryptography password-storage


【解决方案1】:

如果您的系统要求用户输入密码,您可以使用该密码生成密钥来加密/解密其他网站的密码。

这样,您需要您的用户输入该密码才能解密您存储在数据库中的密码。

这里有更详细的流程:

  1. 用户在登录系统时输入密码“123456”。
  2. 你使用“123456”密码的SHA256得到一个密钥:“8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92”
  3. 使用“8d969...”密钥通过 AES 解密数据库中网站的密码。

您可以通过多种方式对此进行优化。例如:在计算 SHA 哈希之前对密码进行加盐。

作为此类加盐的实际示例,Michael 建议使用PBKDF2(以HMACSHA-256 作为其两个参数的伪随机函数)。

其他增强功能:存储密钥的加密版本以允许您的用户更改自己的密码,而无需重新加密他的所有密码......等等......

【讨论】:

  • 问题的描述方式让我觉得其他网站不受他们控制。取决于此,您的解决方案可能是可行的。 @Citizen 你能澄清一下吗?
  • 仅供参考:上面的答案假定无法控制其他网站,因此需要从数据库中检索其实际密码。
  • 以上述方式使用 SHA-256 使其容易受到线性查找和长度扩展攻击,特别是考虑到可以将这些信息的利用与对称密码中的任何漏洞结合使用以获得额外的原始值的上下文。要解决此问题,您需要使用带有 HMAC-SHA-256 的 PBKDF2 之类的东西,而不仅仅是普通的 SHA-256。除非用户每次都需要输入密码,否则您仍然需要密钥管理。
  • 这很好,除非我必须在自动化脚本中使用这些凭据。这不是手动调用的。
  • 但是,我认为这是至少半保护信息的唯一方法。
【解决方案2】:

您可以做任何事情来使用您的凭据,攻击者也可以这样做

混淆实际上给你带来了什么?时间。毕竟数据就在那里,你自己使用它的方案也是如此。有人弄清楚你的计划是什么只是时间问题。这一切都取决于您的偏执程度以及对您感到满意的风险程度的评估。特别是,您如何存储任何凭据应取决于谁有权访问运行数据库的机器。

尽管如此,橡胶最终还是要上路,所以继续前进吧。不要完全敲打混淆。只需确保将其与明智的做法相结合。

方法和建议

为每个帐户生成每个应用程序的 API 密钥,以供机器使用

如果您可以从第三方帐户生成 API 密钥,这将使您能够撤消对帐户的访问权限,而无需关闭所有潜在的应用程序。许多服务都有这些类型的 API 密钥(Google、Twitter、StackExchange、Facebook 和许多其他服务)。

您只需设置一个“应用程序”,然后使用消费者密钥和秘密以及访问令牌和访问秘密。机器只需要存储这些凭据。如果发生妥协,您只需撤销该组密钥。此外,这些允许您指定每个帐户的权限。

为他们的凭据集使用每个用户的密码

当用户登录时,您才能解锁他们的密码集。为此,您将根据适当的散列方案生成一个密钥,并在密钥之前执行几个散列步骤进行验证检查。

无论如何都要在磁盘上加密

您始终可以使用一个密钥来加密凭据。然后,您只有一个要保护的密钥(保护所有其他秘密)。然后,您必须在访问其他凭据之前进行解密。

将秘密存储在系统的密钥环中

在 Linux 上,使用 gnome-keyring。然后您可以进行简单的 Create-Read-Update-Delete 调用,将其视为密码数据库。 Gnome 密钥环基于 PKCS#11 标准。

gnome-keyring has an API 用于保存到密钥环和检索项目。

/* A callback called when the operation completes */
static void
found_password (GnomeKeyringResult res, const gchar* password, gpointer user_data)
{
  /* user_data will be the same as was passed to gnome_keyring_find_password() */
  // ... do something with the password ...
  /* Once this function returns |password| will be freed */
}

static void
find_my_password()
{
  gnome_keyring_find_password (GNOME_KEYRING_NETWORK_PASSWORD,  /* The password type */
                               found_password,                  /* callback */
                               NULL, NULL,     /* User data for callback, and destroy notify */
                               "user", "me", 
                               "server", "gnome.org",
                               NULL);
}

在 Windows 7+ 上,使用“加密文件系统”(EFS) 功能。所有文件都使用证书加密,而证书又受您的 Windows 密码保护。

不过,不要让这让您产生虚假的安全感。如果这是运行它的服务器,如果有人获得了对该盒子的网络访问权限,那么他们自己也可以访问密钥环数据。

设置授予访问权限的远程计算机

您能否设置一台机器,使用公钥和私钥对授予对凭据或解锁密钥的访问权限?

关于散列

如果您对用户名和密码进行哈希处理,您将无法取回它们。哈希被设计为单向函数。

您可以编码数据以进行混淆,但我不建议这样做。

【讨论】:

  • 这不保护数据库,这保护了一些允许访问问题中未描述的 API 的客户端。所描述的系统似乎是某种机器,它使用某种模拟来代表用户自动执行任务。
  • 可以将同一台机器视为客户端。这就是社交媒体网站上的聚合器和抓取工具的工作方式。他们使用 OAuth 凭据访问数据或特定帐户(甚至代表实际客户)。
  • 我开发了一个非常大规模的网络爬虫,它根本不使用 OAuth。此外,该问题从未说明 OAuth 甚至是一个考虑因素。
  • @MichaelJ.Gray 哦,当然。并非所有服务都这样做(也不必是 OAuth 才能拥有 API 密钥)。我建议这样做,以防因不了解特定于应用程序的 API 密钥而遗漏。
  • 我同意特定于应用程序的 API 密钥将是最佳途径,因为它可以避免进行帐户模拟或他们试图做的任何事情。然而,由于这个问题没有描述这一点,我的回答(没有评论被否决)省略了关于他们的架构的任何假设。
【解决方案3】:

如果您对信息进行哈希处理,则以后无法检索它。如果加密它,则需要将密钥存储在某处。除了物理上限制对数据库的访问之外,没有可靠的方法来消除恶意使用数据的可能性。

散列可以以所有可预见的方式阻止对原始数据的使用。但是,您需要使用数据。像 SHA-256 这样的加密哈希的设计使得在给定 H(m) 的情况下很难找到 m(其中 H 是您最喜欢的哈希函数)。

如果你走加密路线,你需要存储加密密钥,它可能会被泄露或至少用作解密预言机。您可以创建一个为您进行解密的服务代理,并使用客户端和服务器身份验证证书来确保安全。但是,如果有人入侵了授权客户端,那么您在入侵和检测到帐户可能被入侵之间有一个时间窗口。但是这种方法让您可以灵活地撤销证书并立即拒绝服务器访问,即使您不再有权访问受感染的客户端。

我建议设置一个远程服务,该服务只能通过直接连接(在同一物理交换机上)使用,它会向客户端验证自身并要求所有客户端进行验证。如果客户受到威胁,也许限制它可以进行的查询数量也有助于防止滥用。该服务需要在每个请求时检查证书吊销。

此服务还需要连接到远程日志记录工具,该工具将用于独立审核系统。此日志服务需要再次验证客户端并通过客户端验证自身。日志服务接收数据并将其附加到日志中,它不允许修改或删除。当它接收到一个日志条目时,它会对一个带有时间戳的日志条目进行数字签名并将其输入到一个审计容器中。

这类似于证书颁发机构设置书面记录以审核证书颁发的方式,以便为妥协提供可能的最佳恢复模型,因为实际上不可能防止妥协。

【讨论】:

    猜你喜欢
    • 2012-10-05
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 2021-07-31
    • 2012-06-05
    • 2022-11-01
    • 1970-01-01
    相关资源
    最近更新 更多