关于生成 OAuth 令牌的最佳实践?

我知道 OAuth 规范并没有指定 ConsumerKey、 ConsumerSecret、 AccessToken、 RequestToken、 TokenSecret 或者 Verifier 代码的来源,但我很好奇是否有创建显著安全令牌(特别是令牌/秘密组合)的最佳实践。

在我看来,有几种创建标记的方法:

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

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

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

加密真实数据(3)将允许解密知道信息。与(1)和(2)相比,这将需要更少的存储和更少的查找,但是潜在的安全性也更低。

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

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

跟进问题 :

是否有一个最小令牌长度来显著加密安全?据我所知,更长的令牌机密将创建更安全的签名。这个理解正确吗?

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

OAuth 规范在 11.10秘密熵中提出了这个问题。

35734 次浏览

OAuth says nothing about token except that it has a secret associated with it. So all the schemes you mentioned would work. Our token evolved as the sites get bigger. Here are the versions we used before,

  1. Our first token is an encrypted BLOB with username, token secret and expiration etc. The problem is that we can't revoke tokens without any record on host.

  2. So we changed it to store everything in database and the token is simply an random number used as the key to the database. It has an username index so it's easy to list all the tokens for an user and revoke it.

  3. We get quite few hacking activities. With random number, we have to go to database to know if the token is valid. So we went back to encrypted BLOB again. This time, the token only contains encrypted value of the key and expiration. So we can detect invalid or expired tokens without going to the database.

Some implementation details that may help you,

  1. Add a version in the token so you can change token format without breaking existing ones. All our token has first byte as version.
  2. Use URL-safe version of Base64 to encode the BLOB so you don't have to deal with the URL-encoding issues, which makes debugging more difficult with OAuth signature, because you may see triple encoded basestring.