有关生成OAuth令牌的最佳做法?


100

我意识到OAuth规范并未指定关于ConsumerKey,ConsumerSecret,AccessToken,RequestToken,TokenSecret或Verifier代码的来源的任何信息,但是我很好奇是否存在创建显着安全的令牌(尤其是Token /秘密组合)。

如我所见,有几种创建令牌的方法:

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

(1)的优点是数据库是看起来最安全的信息的唯一来源。攻击要比(2)或(3)难。

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

加密真实数据(3)将允许解密以了解信息。与(1)和(2)相比,这将需要较少的存储空间并可能需要更少的查找,但是安全性也可能较低。

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

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

遵循问题

是否有最小令牌长度才能显着地确保密码安全?据我了解,更长的令牌机密会创建更安全的签名。这种理解正确吗?

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

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


为什么要加密?哈希不够好吗?如果仅散列就足以用作密码,那么对于较长的访问令牌来说岂不是更好?
AlikElzin-kilaka

自从我问这个问题已经有7.5年了。老实说,我不记得了。
mckamey

1
再次阅读,建议使用哈希和加密是两种不同的方法。加密将允许服务器在不进行数据库查找的情况下获取一些信息。这是许多折衷方案之一。
mckamey

Answers:


93

OAuth关于令牌没有什么说什么,只不过它有一个与之相关的秘密。因此,您提到的所有方案都将起作用。我们的代币随着站点的扩大而演变。这是我们以前使用的版本,

  1. 我们的第一个令牌是带有用户名,令牌密钥和到期时间等的加密BLOB。问题是,如果没有主机上的任何记录,我们就无法撤消令牌。

  2. 因此,我们对其进行了更改,以将所有内容存储在数据库中,而令牌只是一个随机数,用作数据库的密钥。它具有用户名索引,因此可以轻松列出用户的所有令牌并将其吊销。

  3. 我们很少有黑客活动。对于随机数,我们必须进入数据库以了解令牌是否有效。因此,我们再次回到加密的BLOB。这次,令牌仅包含密钥的加密值和有效期。因此,我们无需进入数据库即可检测到无效或过期的令牌。

一些实施细节可能会对您有所帮助,

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

2
太好了,谢谢。版本想法是一个好主意。我已经有了对URL友好的Base64,但是希望我使用严格的字母数字编码,以便于阅读。
mckamey

以前没想到过,很有趣!我正在计划使用APC密钥缓存,以在读取此文件之前避免不必要地加载数据库。仍然不确定这是否不会比共享内存查找APC慢(至少在合理的时间范围内在第二,第三等请求)。
Philzen 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.