ChatGPT解决这个技术问题 Extra ChatGPT

生成 OAuth 令牌的最佳实践?

我意识到 OAuth spec 没有指定有关 ConsumerKey、ConsumerSecret、AccessToken、RequestToken、TokenSecret 或 Verifier 代码来源的任何信息,但我很好奇是否有任何最佳实践来创建非常安全的令牌(尤其是 Token /秘密组合)。

正如我所看到的,有几种创建令牌的方法:

只需使用随机字节,存储在与消费者/用户相关联的数据库中 散列一些用户/消费者特定数据,存储在与消费者/用户相关联的数据库中 加密用户/消费者特定数据

(1) 的优点是数据库是似乎最安全的信息的唯一来源。比 (2) 或 (3) 更难进行攻击。

散列真实数据 (2) 将允许从可能已知的数据重新生成令牌。可能不会真正为(1)提供任何优势,因为无论如何都需要存储/查找。比 (1) 更密集的 CPU。

加密真实数据 (3) 将允许解密知道信息。与 (1) 和 (2) 相比,这将需要更少的存储空间和可能更少的查找,但也可能不太安全。

是否还有其他应考虑的方法/优点/缺点?

编辑:另一个考虑是令牌中必须有某种随机值,因为必须存在过期和重新发行新令牌的能力,因此它不能只包含真实数据。

关注问题:

是否有最小令牌长度以显着提高密码安全性?据我了解,更长的令牌秘密会创建更安全的签名。这种理解正确吗?

从散列的角度来看,使用特定编码是否有优势?例如,我看到很多 API 使用十六进制编码(例如 GUID 字符串)。在 OAuth 签名算法中,Token 被用作字符串。使用十六进制字符串,可用的字符集将比使用 Base64 编码的字符集小得多(更可预测)。在我看来,对于两个长度相等的字符串,具有较大字符集的字符串将具有更好/更宽的哈希分布。在我看来,这将提高安全性。这个假设正确吗?

OAuth 规范在 11.10 Entropy of Secrets 中提出了这个问题。

为什么要加密?哈希还不够好吗?如果只是散列对于密码来说已经足够好了,那么对于更长的访问令牌难道不应该更好吗?
我问这个问题已经 7.5 年了。老实说,我不记得了。
再次阅读,散列和加密是建议的两种不同方法。加密将允许服务器在没有数据库查找的情况下获取一些信息。这是众多交易中的一种。

Z
ZZ Coder

OAuth 对令牌只字未提,只是它有一个与之相关的秘密。所以你提到的所有方案都行得通。我们的代币随着网站变大而演变。这是我们之前使用的版本,

我们的第一个令牌是一个加密的 BLOB,其中包含用户名、令牌秘密和过期时间等。问题是我们无法在主机上没有任何记录的情况下撤销令牌。所以我们将其更改为将所有内容存储在数据库中,并且令牌只是一个随机数,用作数据库的密钥。它有一个用户名索引,因此很容易列出用户的所有令牌并撤销它。我们很少有黑客活动。使用随机数,我们必须去数据库才能知道令牌是否有效。所以我们又回到了加密的 BLOB。这一次,令牌只包含密钥的加密值和过期时间。所以我们可以在不去数据库的情况下检测无效或过期的令牌。

一些可能对您有所帮助的实现细节,

在令牌中添加一个版本,这样您就可以在不破坏现有格式的情况下更改令牌格式。我们所有的令牌都有第一个字节作为版本。使用 Base64 的 URL 安全版本对 BLOB 进行编码,因此您不必处理 URL 编码问题,这会使 OAuth 签名的调试更加困难,因为您可能会看到三重编码的基本字符串。


太好了,谢谢。版本的想法是一个好主意。我已经使用了 URL 友好的 Base64,但我希望我有一个严格的字母数字编码,以便于阅读。
之前没想到,很有意思!在我阅读本文之前,我计划使用 APC 密钥缓存来避免数据库的不必要负载。仍然不确定这是否不会比共享内存查找 APC 慢(至少在合理的时间跨度内的第二、第三等请求)。