Python uuid.uuid4 是否足以用于密码重置链接?

Is Python uuid.uuid4 strong enough for password reset links?

这是我用来为我的应用生成密码重置 link 的代码:

def create_unique_code():
    return str(uuid.uuid4())

够强吗?我使用一两天的到期时间。

是的,UUID4 是完全随机的并且足够长以排除暴力破解或幸运猜测。因此,只要 RNG uuid.uuid4() 提供足够好的随机性,你就应该没问题。

但是,请考虑使用例如一个加密签名的令牌(itsdangerous 库可以处理它)——你不仅可以在生成它时指定一个到期时间,你也不必在你的服务器上存储任何关于令牌的信息。

在CPython中,是的。在其他 Python 实现中,可能是这样,但您可能需要仔细检查是否使用了强大的加密随机源来生成 UUID。


在判断生成安全随机令牌(例如 UUID)的某种方式是否“足够强大”时,您可能会关心两个因素:

  1. 是否有足够的可能值使其不被暴力破解?
  2. 是否使用了随机源cryptographically secure

由于 there are 2122 version 4 UUIDs(即 5 万亿万亿多一点),在这种情况下,第 1 点的答案肯定是“是”。 space 所有可能的 UUID 都不会很快被暴力破解。

第 2 点目前没有被 official Python docs on uuid.uuid4() 回答,没有提到安全性或使用的随机源是否强大。事实上,uuid4() 的整个文档只是:

Generate a random UUID.

这显然不提供安全保证。

UUID specification 也没有解决它,它没有强制要求在 UUID 生成中使用强大的加密随机源,并且确实明确考虑了 "可预测随机数源的可能性“ 用于在 安全注意事项 部分中生成 UUID。

但是,我们可以在 https://github.com/python/cpython/blob/master/Lib/uuid.py:

查看实现
def uuid4():
    """Generate a random UUID."""
    return UUID(bytes=os.urandom(16), version=4)

因为它使用 os.urandom 作为它的随机源,所以它是安全的。请参阅 https://docs.python.org/3/library/os.html#os.urandom 上的文档,其中指出 os.urandom returns:

a string of size random bytes suitable for cryptographic use.