Python 和最多 21 个字符的随机键

标签 python encryption key

我正在使用一个 api,它的名称最多为 21 个字符,代表一个内部 session ,其生命周期大约为“两天”。我不希望使用某种 hasing 使名称变得有意义? md5 生成 40 个字符,还有什么我可以使用的吗?

现在我使用 'userid[:10]' + 创建时间:ddhhmmss + 随机 3 个字符。

谢谢,

最佳答案

如果我没看错你的问题,你想生成一些最多 21 个字符的任意标识符 token 。它是否需要高度抵抗猜测?您给出的示例不是“密码学上强大的”,因为可以通过搜索不到整个可能键空间的 1/2 来猜测它。

您没有说明字符是否可以全部为 256 个 ASCII 字符,或者是否需要限制为可打印的 ASCII(33-127,包括在内)或更小的范围。

有一个为 UUID 设计的 Python 模块s(通用唯一标识符)。您可能需要生成随机 UUID 的 uuid4,并在可用时使用操作系统支持(在 Linux、Mac、FreeBSD 和可能的其他操作系统上)。

>>> import uuid
>>> u = uuid.uuid4()
>>> u
UUID('d94303e7-1be4-49ef-92f2-472bc4b4286d')
>>> u.bytes
'\xd9C\x03\xe7\x1b\xe4I\xef\x92\xf2G+\xc4\xb4(m'
>>> len(u.bytes)
16
>>> 

16 个随机字节是非常难以猜测的,如果您只想拥有一个不可猜测的不透明标识符,则无需使用您的 API 允许的完整 21 个字节。

如果你不能像那样使用原始字节,这可能是个坏主意,因为它更难在日志和其他调试消息中使用,也更难通过肉眼进行比较,然后将字节转换成更易读的东西,比如使用 base-64 编码,结果缩减为 21(或其他)字节:

>>> u.bytes.encode("base64")
'2UMD5xvkSe+S8kcrxLQobQ==\n'
>>> len(u.bytes.encode("base64")) 
25
>>> u.bytes.encode("base64")[:21]
'2UMD5xvkSe+S8kcrxLQob'
>>> 

这为您提供了一个非常高质量的长度为 21 的随机字符串。

您可能不喜欢 base-64 字符串中的“+”或“/”,因为如果不进行适当的转义,可能会干扰 URL。由于您已经考虑使用“随机 3 个字符”,因此我认为这不是您的担心。如果是,您可以将这些字符替换为其他字符('-' 和 '.' 可能有效),或者删除它们(如果存在)。

正如其他人所指出的,您可以使用 .encode("hex") 并获得等效的十六进制,但这只是 4 位随机性/字符 * 21 个字符最多给您 84 位随机性而不是两倍。每一位都会使您的 key 空间加倍,从而使理论上的搜索空间小得多。缩小了 2E24 倍。

即使使用十六进制编码,您的 key 空间大小仍然是 2E24,所以我认为这更多是理论上的问题。我不担心有人会对您的系统进行暴力攻击。

编辑:

P.S.:uuid.uuid4 函数使用 libuuid(如果可用)。它从 os.urandom(如果可用)获取它的熵,否则从当前时间和本地以太网 MAC 地址获取。如果 libuuid 不可用,则 uuid.uuid4 函数直接从 os.urandom(如果可用)获取字节,否则它使用随机模块。 random 模块使用基于 os.urandom(如果可用)的默认种子,否则使用基于当前时间的值。每次函数调用都会进行探测,因此如果您没有 os.urandom,那么开销会比您预期的要大一些。

带回家消息?如果你知道你有 os.urandom 那么你可以做

os.urandom(16).encode("base64")[:21]

但如果您不想担心它的可用性,那么请使用 uuid 模块。

关于Python 和最多 21 个字符的随机键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/621649/

相关文章:

Javascript:抓取数组中特定值之前和之后的值

Ruby - 将两个散列与一些类似的键合并

python - 如何使用 statsmodels 获取多元线性回归的标准化(Beta)系数

python - Pycrypto - 在 Linux 上加密/在 Windows 上解密

python - python中的嵌套dict,根据内部键搜索获取内部值和父键

Android 从 CipherInputStream 读取文件而不重写文件

java - 在 Java 中写入/保存文件的问题

python - Cython cimport 找不到 .pxd 模块

python - 如何使用单个打印语句确定行索引?

python - 将字符串中的每个其他字母大写