dak*_*aka 3 python security token python-3.x
使用 Python 的秘密库 ( https://docs.python.org/3/library/secrets.html )生成的令牌发生冲突的可能性有多大?
似乎没有提到它们的独特性。
该secrets模块的目的是获取秘密数据,即无法预测或逆向工程的信息
secrets 模块提供对操作系统提供的最安全的随机源的访问。
通常,操作系统将使用多个熵源来生成位。例如进程 id、线程 id、鼠标/键盘输入时间、CPU 计数器、系统时间等。
只要熵的数量对于生成的比特数量来说足够大(并且操作系统再次使用许多源并不断累积熵),我们应该期望所有值的均匀分布。因此,如果您生成 32 位密钥,您应该会看到 4294967296 个值中的每一个都具有相似的频率。
为了估计我们预计碰撞前多久,我们主要看生日问题。一般来说,如果值是均匀分布的,并且值的数量是n,我们应该期望在生成约sqrt(n)值后会发生碰撞(尽管实际上它会更多)。
您可以使用快速基准程序验证这一点
import secrets
def find_collision(b):
tokens = set()
while True:
token = secrets.token_bytes(b)
if token in tokens:
return len(tokens)
tokens.add(token)
b = 4
samples = 100
l = [find_collision(b) for i in range(samples)]
avg = sum(l)/len(l)
print(f'n = {2**(b*8)}, sqrt(n) = {2**(b*8/2)}')
print(f'on average, with a {b} byte token, a collision occurs after {avg} values')
Run Code Online (Sandbox Code Playgroud)
n = 4294967296, sqrt(n) = 65536.0
on average, with a 4 byte token, a collision occurs after 75797.78 values
Run Code Online (Sandbox Code Playgroud)
secrets没有关于唯一性的目标或主张,因为目标是生成高熵、随机字节,这些字节应该是不可能预测或逆向工程的。向模块添加约束以防止重复本质上会使其更具可预测性。此外,secrets在假设您获取所需内容并以您喜欢的方式使用它的情况下,在流中为您提供这些字节,因此防止重复作为上游责任没有多大意义。这与 UUID 之类的东西形成对比,它具有固定的宽度,旨在用作便携式标识符和可识别的数据类型。