4

我正在获取十六进制数字以生成唯一的随机激活器链接,例如:

hostname/account/confirm/$randomHex

实际上,通过搜索,我使用 PHP 的随机十六进制可能是:

bin2hex( openssl_random_pseudo_bytes(16) )

上面生成了一个包含 32 个十六进制数字的字符串,我希望使用较短的长度作为 12 个十六进制数字。

考虑到计算机的功率处理,我可以使用的十六进制的最小尺寸是多少?

4

2 回答 2

2

16 个随机生成的字节给出 128 位的熵。使用离线暴力攻击无法破解具有 128 位熵的密钥。即使世界上每台计算机都在努力破解它。

但是,您希望防止速度较慢的在线暴力攻击。如果你想要 12 个十六进制字符,这将是 6 个字节,因此是 48 位熵。这为您提供了 281,474,976,710,656 种可能性。如果您的站点需要 0.25 *秒来响应,那么2^47 * 0.25 = 35,184,372,088,832通过向您的站点发出请求(111.6 万年)平均需要几秒钟来暴力破解。

使用 48 位是安全的。

*实际上,这将是一次并行攻击,因此如果攻击者所做的只是验证帐户,他们就不必等待响应。但是,任何系统都会有速率限制,从而减慢攻击速度。根据需要调整数字以适合您的系统。

于 2015-08-22T08:05:49.687 回答
2

考虑到计算机的功率处理,我可以使用的十六进制的最小尺寸是多少?

如果您有一个威胁模型,这实际上是一个容易计算的数字。

根据您提供的 URL,您似乎正在生成一个用于电子邮件所有权验证的 URL。这绝对比密码重置 URL 更需要。

如果您限制错误尝试(即阻止他们的 IP 地址在 24 小时内再次尝试),您可以使用 8 个十六进制字符(32 位)来解决问题,这意味着他们将能够在之后猜出有效的确认链接65,536 次尝试,概率为 50%。(生日悖论。)实现这一目标还需要 65,536 个 IP 地址,只是为了盲目地确认某人的电子邮件地址(可能不是他们自己的)。

然而!

如上所述,如果您将其用于例如恢复功能(我忘记了密码),请不要忽略 string length。128 位(32 十六进制,16 原始二进制)应被视为下限。为了安全起见,我会说拍摄 256 位。

上面生成了一个包含 32 个十六进制数字的字符串,我希望使用较短的长度作为 12 个十六进制数字。

如果要提高给定长度的字符串的安全性,唯一的方法是增加字符串中每个字符的可能值的数量。

即使您使用的不是原始二进制文件,11 个字符的上限也是 88 位熵。指定十六进制会将您减少到 44(但很可能是 40,因为您可能会bin2hex(random_bytes(5))在这里写)。

如果您想安全地生成具有任意字母的固定大小字符串,请查看此 StackOverflow 答案

于 2015-08-20T20:43:04.393 回答