在将 API 密钥存储到数据库之前,我是否需要对其进行散列或加密?

信息安全 哈希 密钥管理 网络服务 休息 api
2021-09-03 02:01:32

我正在保护对我正在使用 API 密钥构建的 REST 服务的 API 调用。该计划是:

  1. 当我们获得一个新客户端时,生成一个 API 密钥(一个 UUID)。
  2. 通过电子邮件将 API 密钥发送给他们。
  3. 他们在每次调用我们的服务时发送 API 密钥(通过 HTTPS)。我们将在我们的数据库中查找 API 密钥(首先对其进行加密或散列)并找出 API 密钥用于的帐户。

最终,我们将为所有这些添加用户帐户和门户,以便客户无需我们参与即可生成和停用 API 密钥。

我的问题在最后一部分。在将 API 密钥存储到数据库之前,我应该对它们进行散列还是加密(或保持未加密?)?我试图理解其中的含义。我知道,如果我对它们进行哈希处理,那么如果他们获得数据库访问权限,我就会防止有人知道所有 API 密钥。但是我应该考虑的其他事情是什么?例如,是否有性能原因来做一个优于另一个?

2个回答

是的,您绝对应该散列您的 API 密钥。实际上,它们是您的密码,应该这样对待。请注意,这是散列的 - 未加密。您永远不需要解密 API 密钥,因此您应该无法解密。

正如saghaulor所说,您需要确保使用版本 4 UUID(即随机的),并且在生成它们时使用加密安全的随机源。由于正确生成的 UUID 包含122 位熵,因此您不必担心加盐或使用像 bcrypt 这样的慢散列函数。一轮 SHA-256 就足够了。

您的设计中存在问题的部分是您为用户提供了通过邮件传递的“密码”,并且他们无法更改。对于有安全意识的用户来说,这可能还不够好。也许你提到的门户会解决这个问题。

1) 确保您使用安全的随机生成器来生成您的 UUID。

2) 不要通过电子邮件发送 API 密钥。电子邮件不能保证安全传输,也就是说,您很可能以明文形式发送密钥。

3) 您如何实现身份验证机制将影响您如何存储 API 密钥。

如果您打算使用 API 密钥作为主密钥,那么您不能对其进行散列或加密,因为如果您正确地散列或加密,搜索实际上是不可能的。

如果您提供给用户的是主密钥和 API 密钥的组合,那么您可以安全地存储 API 密钥。由于密钥实际上是密码,因此建议使用散列法就足够了。

请记住正确使用算法。通常,散列需要为每条记录添加盐。有不同的哈希算法。有些,比如 bcrypt 和 scrypt 可以增加人为的延迟来减缓暴力破解。这可能适合也可能不适合您的用例。不推荐使用某些算法,例如 MD5 和 SHA1,因为它们已被证明是不安全的。

您可以在没有盐的情况下对密钥进行哈希处理,然后您可以进行简单的搜索。这不会像使用盐散列那样安全,但所述方法的安全性可能足以满足您的目的。