python中uuid4和秘密token_bytes有什么区别?

voi*_*oid 5 random uuid operating-system cryptography python-3.x

检查了 cpython 源代码中的Secretsuuid4。两者似乎都在使用 os.urandom。

#uuid.py
def uuid4():
    """Generate a random UUID."""
    return UUID(bytes=os.urandom(16), version=4)

#secrets.py
def token_bytes(nbytes=None):
    """Return a random byte string containing *nbytes* bytes.
    If *nbytes* is ``None`` or not supplied, a reasonable
    default is used.
    >>> token_bytes(16)  #doctest:+SKIP
    b'\\xebr\\x17D*t\\xae\\xd4\\xe3S\\xb6\\xe2\\xebP1\\x8b'
    """
    if nbytes is None:
        nbytes = DEFAULT_ENTROPY
    return _sysrand.randbytes(nbytes)

# This is code for randbytes in SystemRandom in random
 def randbytes(self, n):
        """Generate n random bytes."""
        # os.urandom(n) fails with ValueError for n < 0
        # and returns an empty bytes string for n == 0.
        return _urandom(n)
Run Code Online (Sandbox Code Playgroud)

IETF 警告不要使用 uuid 来实现安全功能。请参阅第 6 节UUID。它说

  1. 安全考虑

不要假设 UUID 很难猜测;例如,它们不应该被用作安全功能(仅拥有即可授予访问权限的标识符)。可预测的随机数源会使情况恶化。

如果 Secrets 确实使用与 uuid4 相同的 urandom,我们可以使用 uuid4 代替 Secrets 吗?使用秘密 token_bytes 而不是 uuid4 本身的全部目的是什么?根据 IETF 的标准,API 密钥/令牌的秘密模块真的不安全吗?

Maa*_*wes 2

您可能会惊讶地发现随机 UUID 并不是完全随机的。准确地说,有 6 位设置为特定值(以表明它是一个随机 UID)。它们被创建为独特的 (具有高度的确定性)。UUID 有特定的用途,因此您会发现在它们上定义的各种方法。

此外,顾名思义,它们并不意味着秘密。这也可能意味着没有采取适用于秘密的可能的保护措施。例如,字符串通常很容易在内存中找到,并且 UUID 经常以文本表示形式使用/传达。

令牌是不同的东西。它通常被加密并保密。因此,它有不同的目的。当然,UUID 和令牌都可以由随机位和字节组成。然而,这更多的是关于使用正确的工具来完成工作。

如果您要创建密钥而不是令牌或 UUID,我更喜欢使用特定于 API 的方法来生成密钥。否则直接使用可能是个好主意SystemRandom,因为密钥既不是 UUID 也不是令牌。