我意识到 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 中提出了这个问题。
OAuth 对令牌只字未提,只是它有一个与之相关的秘密。所以你提到的所有方案都行得通。我们的代币随着网站变大而演变。这是我们之前使用的版本,
我们的第一个令牌是一个加密的 BLOB,其中包含用户名、令牌秘密和过期时间等。问题是我们无法在主机上没有任何记录的情况下撤销令牌。所以我们将其更改为将所有内容存储在数据库中,并且令牌只是一个随机数,用作数据库的密钥。它有一个用户名索引,因此很容易列出用户的所有令牌并撤销它。我们很少有黑客活动。使用随机数,我们必须去数据库才能知道令牌是否有效。所以我们又回到了加密的 BLOB。这一次,令牌只包含密钥的加密值和过期时间。所以我们可以在不去数据库的情况下检测无效或过期的令牌。
一些可能对您有所帮助的实现细节,
在令牌中添加一个版本,这样您就可以在不破坏现有格式的情况下更改令牌格式。我们所有的令牌都有第一个字节作为版本。使用 Base64 的 URL 安全版本对 BLOB 进行编码,因此您不必处理 URL 编码问题,这会使 OAuth 签名的调试更加困难,因为您可能会看到三重编码的基本字符串。
不定期副业成功案例分享