为什么电子邮件确认码不能是 UUID?

Why can't an email confirmation code be a UUID?

从阅读 Whosebug 来看,简单地使用 UUID 通过电子邮件确认注册似乎是不好的。这是为什么?为什么我需要花哨地从用户数据中生成一些随机性较低的代码?

建议的方法似乎是用户数据 + salt -> hash 的变体。使用 UUID 时,它总是会被散列。这是为什么?没有什么可以隐藏或混淆的,对吧?

抱歉,如果这个问题很愚蠢。

现在我正在使用 Python3 的 UUID 内置函数(制作原型)。他们有什么特别之处吗?

电子邮件验证的要点是,可以防止有恶意的人注册任意电子邮件地址而无需访问他们各自的收件箱(想想一个恶作剧者想要为每日猫事实注册一个目标,或更多险恶地为某人注册付费电子邮件时事通讯或向他们的收件箱(可能是他们的工作收件箱)发送垃圾邮件,其中包含明确的内容)。因此,确认代码必须是加密安全的。加密安全确认码的一个重要特征是,它无法预测或猜测。

这就是 UUID 不适用的原因:UUID 的主要特点是,从天文角度来看,碰撞不太可能发生。然而,UUID 生成算法并不是设计成不可预测的。通常,UUID 是从生成系统 MAC 地址、生成时间和一些熵生成的。 MAC地址和时间都定好了。使用仅由 PID 和时间提供的 PRNG 也是完全允许的。 UUID 的全部意义在于避免冲突,而不是让它们不可预测或不可猜测。为此,只要有生成系统唯一的位(永远不会改变)和一些位来防止这个特定系统通过及时分发 UUID、生成它的进程和进程内部状态来两次生成相同的 UUID 就足够了.

所以如果我知道哪个系统将生成一个 UUID,即知道它的 MAC 地址,UUID 生成的时间,只有一些额外的 32 位左右的随机熵UUID。安全方面,32 位根本无法解决问题。

假设确认令牌在 24 小时内有效,每秒可以 >100 个确认请求,并且 UUID 生成器具有 32 位额外随机性(除了时间和 MAC,我们也假设已知)这有 2% 的机会找到有效的确认 UUID。

请注意,如果每个时间间隔尝试的无效 UUID 太多,您将无法 "block" 确认请求,因为这会有效地为攻击者提供一个 DoS 工具来阻止合法用户确认他们的电子邮件地址(还包括确认请求中的电子邮件地址没有帮助;这只允许针对 DoS 的特定电子邮件地址)。