只使用秘密作为 API 密钥的理由?

信息安全 验证 api
2021-09-05 00:33:05

许多受 API 密钥保护的 API 仅使用密钥(即密码),而没有帐户 ID 或用户名之类的东西。

例如 Stripe API 使用密钥作为 Basic Auth 中的用户名,密码留空:

curl https://api.stripe.com/v1/charges \
   -u sk_test_BQokikJOvBiI2HOWgH4olfQ2:

这在服务器端如何工作?它是否以纯文本形式在以秘密作为主键的表中查找秘密?如果这张表被泄露会发生什么?

为什么这比account_id:secret_key在身份验证中使用组合更好?然后,您可以使用作为主键bcrypt(secret_key)而不是secret_key纯文本存储。account_id

相关,但不一样

3个回答

这些 API密钥通常称为令牌。它们通常被认为具有相当短的生命周期,并且或多或少地用作高级会话 ID。它不是真正的会话,因为它们用于无状态请求并且仅携带用户标识。但它们的寿命通常从几个小时到几天不等。而且,它们从来都不是主要的访问密钥,因此如果令牌数据库遭到破坏,它会立即被清空,并且用户会要求新的 API 密钥。

正如 nbering 已经指出的那样,没有什么让这变得不那么安全了。在数据库中搜索hash(secret)而不是account_id.

从攻击者的角度来看,猜测 API 密钥非常困难(其中大多数都相当大)。使用该方案account_id:secret(假设秘密是 API 密钥,而不是用户密码)当然会增加更多的安全性,但没有实际效果(帐户名很少是秘密,因此获取它们并不难。没有攻击者会随机猜测一个,除了猜一个键)。

此外,请考虑使用这些 API 密钥的位置。最有可能在自动化过程中(即一个 python 脚本做一些工作)。要求开发人员添加帐户名称,强制他们将其写入代码或某些配置文件。如果发生攻击,我宁愿丢失我的 API 密钥,我可以轻松地撤销并交换一个新的,而不是丢失我account_id API key. 使用account_id,攻击者只需要密码即可劫持您的帐户,与长 API 密钥相比,这可能不太安全(所以从学术上讲,添加account_id甚至会削弱您的安全性,而省略它并不会真正降低它)。

许多受 API 密钥保护的 API 仅使用密钥(即密码),而没有帐户 ID 或用户名之类的东西。

API 密钥或通常称为令牌,在通过正确的 account_id 和密码成功认证后提供。这可以在 API 调用期间完成,因此客户端提供一次其凭据以获取密钥,该密钥又用于后续 API 调用。相同的凭据用于撤销或更新令牌。

为什么这比在身份验证中使用 account_id:secret_key 组合更好?

API旨在允许系统之间的通信,而不是旨在与用户直接交互,在我看来,帐户ID与识别(客户端)系统具有不同的含义。

然而,最好使用令牌而不是 account_id/password 的主要原因是避免密码通过网络频繁循环。记住 API 的无状态特性,它使客户端在每个请求上都提供凭据。