August Rush

一个还在努力成长的小火汁!

游龙当归海,海不迎我自来也。

We create our own demons.

You can reach me at augustrush0923@gmail.com
secrets --- 生成安全随机数字用于管理密码
发布:2020年09月14日 | 作者:augustrush | 阅读量: 754

Python 3.6新增的模块:secrets secrets 模块可用于生成高加密强度的随机数,适应管理密码、账户验证、安全凭据和相关机密数据管理的需要。

特别地,应当优先使用 secrets 来替代 random 模块中默认的伪随机数生成器,后者被设计用于建模和仿真,而不适用于安全和加密。

参见:PEP 506

随机数

通过secrets模块可以访问你的操作系统所能提供的最安全的随机性来源。

secrets.choice(sequence) 返回一个非空序列中随机选取的元素。

>>> secrets.choice(range(1, 100))
39


secrets.randbelow(n) 返回一个[0, n)范围之内的随机整数。

>>> secrets.randbelow(100)
82


secrets.randbits(k) 返回一个具有k个随机比特位的整数。

>>> secrets.randbits(4)
12


通过secrets源码可以看出,choice,randbelow,randbits其实都是调用的random.SystemRandom下的

# secrets.py
_sysrand = SystemRandom()
randbits = _sysrand.getrandbits
choice = _sysrand.choice

def randbelow(n):
    ...
    return _sysrand._randbelow(n)


生成凭据

secrets模块提供了一些安全凭据的函数,适用于诸如密码重置,难以猜测的URL之类的应用场景

secrets.token_bytes([nbytes=None]) 返回一个包含nbytes个字节的随机字符串。如果nbytes为None或未提供,则会使用一个合理的默认值。

>>> secrets.token_bytes(16)
b'\x96\xb6-\xcb\x95\x98\xef m\xe2\n\xe0UX\x13\xbb'


secrets.token_hex([nbytes=None]) 返回一个十六进制数码形式的随机字符串。字符串具有nbytes个随机字节,每个字节转换为两个十六进制数码。如果nbytes为None或未提供,则会使用一个合理的默认值。


>>> secrets.token_hex(16)
'c454157937748f42e40a1ba2bd9c53fc'


secrets.token_urlsafe([nbytes=None]) 返回一个URL安全的随机字符串,包含nbytes个随机字节。文本将使用Base64编码,因此平均来说每个字节将对应 1.3 个结果字符。 如果 nbytes 为 None 或未提供,则会使用一个合理的默认值。


>>> secrets.token_urlsafe(16)
'zrJx_H3woFN0AYsKe1ZkKA'


凭据应当使用多少个字节?

为了在面对 暴力攻击 时保证安全,凭据必须具有足够的随机性。 不幸的是,对随机性是否足够的标准会随着计算机越来越强大并能够在更短时间内进行更多猜测而不断提高。 在 2015 年时,人们认为 32 字节(256 位)的随机性对于 secrets 模块所适合的典型用例来说是足够的。

作为想要自行管理凭据长度的用户,你可以通过为各种 token_* 函数指定一个 int 参数来显式地指定凭据要使用多大的随机性。 该参数以字节数来表示要使用的随机性大小。

在其他情况下,如果未提供参数,或者如果参数为 None,则 token_* 函数将改用一个合理的默认值(DEFAULT_ENTROPY = 32)。

**注解**: 该默认值可能在任何时候被改变,包括在维护版本更新的时候。

应用技巧与最佳实践

生成长度为八个字符的字母数字密码:

import string
import secrets
alphabet = string.ascii_letters + string.digits
password = ''.join(secrets.choice(alphabet) for i in range(8))
'''
输出结果:
Z8Gqq4
'''


生成长度为十个字符的字母数字密码,其中包含至少一个小写字母,至少一个大写字母以及至少三个数字:

import string
import secrets

while True:
    password = ''.join(secrets.choice(alphabet) for i in range(10))
    if (any(c.islower() for c in password)
            and any(c.isupper() for c in password)
            and sum(c.isdigit() for c in password) >= 3):
        break
print(password)
'''
输出结果:
Wbpm72G4FD
'''


生成难以猜测的临时 URL,其中包含适合密码恢复应用的安全凭据:

url = 'https://hdcheung.cn/result=' + secrets.token_urlsafe()
print(url)
'''
输出结果:
https://hdcheung.cn/result=c3enB1fVKmlYNBhhYK7APSdc4al8wcHeln90rIsCdxw
'''


  • 标签云

  • 支付宝扫码支持一下

  • 微信扫码支持一下



基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建

京ICP备20007446号-1 & 豫公网安备 41100202000460号

网站地图 & RSS | Feed