【发布时间】:2010-10-23 12:06:46
【问题描述】:
如何在 Python 中生成唯一的会话 ID?
【问题讨论】:
-
Python 3.6+ 的正确答案是:stackoverflow.com/a/55661405
如何在 Python 中生成唯一的会话 ID?
【问题讨论】:
Python 3.6 使这里的大多数其他答案都有些过时了。包括 3.6 及更高版本在内的版本包括 secrets 模块,该模块正是为此目的而设计的。
如果您需要为网络上的任何目的生成加密安全字符串,请参阅该模块。
https://docs.python.org/3/library/secrets.html
例子:
import secrets
def make_token():
"""
Creates a cryptographically-secure, URL-safe string
"""
return secrets.token_urlsafe(16)
使用中:
>>> make_token()
'B31YOaQpb8Hxnxv1DXG6nA'
【讨论】:
更新:2016-12-21
在过去的 5 年里发生了很多事情。 /dev/urandom 已更新,现在被认为是现代 Linux 内核和发行版上的高熵随机源。在过去的 6mo 中,我们看到了使用 Ubuntu 的 Linux 3.19 内核上的熵饥饿,所以我认为这个问题还没有“解决”,但是当要求任何数量的随机性时,最终得到低熵随机性已经足够困难了来自操作系统。
我不想这么说,但就“安全会话 ID”而言,此处发布的其他解决方案均不正确。
# pip install M2Crypto
import base64, M2Crypto
def generate_session_id(num_bytes = 16):
return base64.b64encode(M2Crypto.m2.rand_bytes(num_bytes))
uuid() 或 os.urandom() 都不是生成会话 ID 的好选择。两者都可能产生随机结果,但随机并不意味着它是安全的,因为它的熵很差。请参阅 Haldir 的“How to Crack a Linear Congruential Generator”或NIST's resources on Random Number Generation。如果您仍想使用 UUID,请使用使用良好初始随机数生成的 UUID:
import uuid, M2Crypto
uuid.UUID(bytes = M2Crypto.m2.rand_bytes(num_bytes)))
# UUID('5e85edc4-7078-d214-e773-f8caae16fe6c')
或:
# pip install pyOpenSSL
import uuid, OpenSSL
uuid.UUID(bytes = OpenSSL.rand.bytes(16))
# UUID('c9bf635f-b0cc-d278-a2c5-01eaae654461')
M2Crypto 是 Python atm 中最好的 OpenSSL API,因为维护 pyOpenSSL 似乎只是为了支持旧版应用程序。
【讨论】:
os.urandom 旨在适合加密使用,但不幸的是,情况并非总是如此。 FreeBSD 和 OS-X 为 urandom 提供了一个很好的资源池,Linux 时好时坏(尽管越来越好)。显式总比隐式好。顺便说一句,我发布此内容的原因是因为我在未检查会话 ID 冲突并且用户看到彼此信息的真实世界情况下遇到了会话 ID 冲突。原因? urandom 没有正确播种。 :-/ 现实有时会咬人。
os.urandom 的随机性不足以保证安全,而 OpenSSL(例如通过 M2Crypto)更好。同时@ramirami 声称(也没有证据)实际上两者都使用相同的潜在熵源。我不知道谁是对的,但无论如何我都投反对票;我不喜欢 FUD 和这里的大胆声明(os.urandom 使用或可能在某些平台上使用比 OpenSSL 更糟糕的熵源,以至于前者在后者安全的情况下被密码破解)需要证实有用。
import os, base64
def generate_session():
return base64.b64encode(os.urandom(16))
【讨论】:
它可以像创建一个随机数一样简单。当然,您必须将会话 ID 存储在数据库或其他东西中,并检查您生成的每个 ID 以确保它不是重复的,但如果数字足够大,很有可能永远不会。
【讨论】:
您可以像这样使用uuid library:
导入 uuid my_id = uuid.uuid1() # 或 uuid.uuid4()【讨论】:
Version 4 UUIDs use a scheme relying only on random numbers.,它对会话令牌有什么不好? uuid5 和 uuid1 不是基于随机数的,那为什么 uuid4 不好呢?