所以我想要一种方法来生成一个身份验证令牌以传递回客户端,然后它可以使用它来传递每个请求。
然而,生成具有……的独特令牌的最佳实践是什么?
您可以使用UUID,Universally Unique IDentifier。规格是 rfc4122 。
的 摘录: 强>
使用UUID的主要原因之一是没有集中化 管理它们需要权限(尽管一种格式使用 IEEE 802节点标识符,其他不标识。结果,生成 按需可以完全自动化,并用于各种 目的。这里描述的UUID生成算法非常支持 如果,每台机器的高分配率高达每秒1000万 必要的,以便它们甚至可以用作交易ID。
的 UUID发电机 强>
有各种语言的UUID生成器,只需确保实现使用RFC-4122规范中的算法。其中很多只是为UUID的每个十六进制八位字节使用随机数,这将导致冲突。
我猜你已经有了一个存储这些令牌的数据库,以便你可以检查它是否是正确的。如果这是真的,你可以按照自己喜欢的方式生成令牌(即uniqid(),随机字符串,......无论你喜欢什么),并检查数据库中是否已存在。它如果不存在你就可以使用它,否则你可以生成一个新的并再次检查。
很大程度上归结为代码可以变成多长时间,你需要多大程度的独特性,不可预测的难度,以及你是否有一个有效代码列表。
的 长度 强>
首先:简单数学意味着如果你必须能够生成无数个唯一的独特随机字符串,那么你就不能限制所述字符串的长度(它将变为无限......)。
如果必须将使用的值存储在数据库中,则通常需要最大长度。
无论如何,无限长度的琴弦会产生很多危险。
的 多么独特? 强>
显然,仅仅使用时间并不是非常独特,但是你可以添加一些东西以使碰撞越来越不可能,同时让它更难以预测。
如果您有(当前)有效代码列表,则始终可以针对现有数据库验证生成的代码,并在与当前有效代码发生冲突时重新生成新代码。
显然,一个简单的增加计数器将保证唯一性,但它不方便,因为它不是长度有限,非常可预测等。
的 很难预测 强>
通常,可以猜到的认证码是一种可怕的安全性想法。所以你需要防范这一点。
的 将它们结合起来 强>
要将它们全部组合起来,您可以创建一个字符串的串联:
你不需要全部,订单等都取决于你。越多越好。
一旦你有了这个字符串,你选择一个哈希函数,哈希输出的时间越长,冲突的可能性就越小,但代码将在你的数据库中使用的存储空间越多。
现在一个不错的选择是sha-1或sha-256(md5有点太破碎而无法用于任何新的东西)。
这为您提供了一个长度固定的代码,即使您只是在输入中更改一位,也几乎无法预测攻击者,并且几乎不可能导致冲突,因此会发生显着变化。
多么小?这是极不可能的,请看这里的数学: https://crypto.stackexchange.com/questions/24732/probability-of-sha256-collisions-for-certain-amount-of-hashed-values
如果您需要完全排除这种可能性并且不允许无限长度的代码,您只能根据使用的代码进行检查,如果找到它,您可以生成一个新代码。
的 TL; DR 强>
您可以添加其他时间,例如连接的远程端的IP地址,伪随机数,进程ID,保密的固定字符串等,将其混合并使用例如哈希值进行哈希处理。 sha-256,你有一个很难预测代码的固定长度。
存在冲突的风险,但如果你给它足够的输入,它就会非常小,以消除冲突:检查使用中的代码列表。
这个方法对我有用......
$token = md5(date['u']);
使用自纪元(1970年1月1日)以来的秒数,因此几乎可以保证您获得唯一的一次性值。 MD5将其转换为32个字符的字符串。 2个相同值的可能性仍然不是很大,但非常接近于零。
由于DST,使用日期w /'u'参数不会成为问题。