Python Django-make_random_密码方法,真的是随机的吗?
我使用以下方法为用户创建随机代码,作为预订过程的一部分:Python Django-make_random_密码方法,真的是随机的吗?,python,django,random,Python,Django,Random,我使用以下方法为用户创建随机代码,作为预订过程的一部分: User.objects.make_random_password() 当用户出现在会场时,他们将出示密码 假设两个人不会得到相同的代码,安全吗 谢谢不,假设两个人不能拥有相同的代码是不安全的。随机并不意味着唯一。这可能不太可能,也很少见,这取决于您指定的长度和正在处理的用户数。但是你不能依赖它的唯一性。这取决于你现在有多少用户,你选择的密码长度,以及你如何使用User.objects 此方法是使用。来自django github回购
User.objects.make_random_password()
当用户出现在会场时,他们将出示密码
假设两个人不会得到相同的代码,安全吗
谢谢不,假设两个人不能拥有相同的代码是不安全的。随机并不意味着唯一。这可能不太可能,也很少见,这取决于您指定的长度和正在处理的用户数。但是你不能依赖它的唯一性。这取决于你现在有多少用户,你选择的密码长度,以及你如何使用
User.objects
此方法是使用。来自django github回购协议:
def get_random_string(length=12,
allowed_chars='abcdefghijklmnopqrstuvwxyz'
'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'):
"""
Returns a securely generated random string.
The default length of 12 with the a-z, A-Z, 0-9 character set returns
a 71-bit value. log_2((26+26+10)^12) =~ 71 bits
"""
if not using_sysrandom:
# This is ugly, and a hack, but it makes things better than
# the alternative of predictability. This re-seeds the PRNG
# using a value that is hard for an attacker to predict, every
# time a random string is required. This may change the
# properties of the chosen random sequence slightly, but this
# is better than absolute predictability.
random.seed(
hashlib.sha256(
"%s%s%s" % (
random.getstate(),
time.time(),
settings.SECRET_KEY)
).digest())
return ''.join([random.choice(allowed_chars) for i in range(length)])
根据github,当前代码默认使用62个字符(小写和大写字母和数字)字符串中的12个字符的密码。这使得62**12或322626676239789821056(3.22e21)可能使用不同的密码。这比目前的世界人口(约7e9)要大得多
字母由random.choice()
函数从此字符列表中选取。现在的问题是重复调用random.choice()
返回相同序列两次的可能性有多大
从get\u random\u string()
的实现中可以看出,代码尽量避免可预测性。当不使用操作系统的伪随机值生成器时(在Linux和*BSD上,伪随机值生成器从以太网数据包或按键到达的时间等收集真实的随机性),它会在每次调用时使用当前随机状态、当前时间和(可能是恒定的)密钥的组合对模块的可预测PRNG进行重新播种
因此,对于要生成的两个相同密码,随机生成器的状态(在python中约为8kib)和生成密码的时间(根据time.time()
)必须是相同的(从纪元开始以秒为单位)。如果系统的时间得到了很好的维护,并且您正在运行一个密码生成程序实例,那么发生这种情况的可能性基本为零。如果您同时启动此密码生成程序的两个或多个实例,并且使用完全相同的PRNG种子,并组合它们的输出,则可能会出现多次密码。此外,如果您确实希望唯一性,您可以使用随机生成的字符串与添加到末尾的计数器值的组合,每次添加用户时计数器值都会递增。如果该计数器的宽度足够大,足以对抗您的用户,则可以保证您的唯一性。感谢您简洁的响应。我得到了每次添加用户时递增1的概念,但您所说的“该计数器的宽度足够大,足以对抗您的用户”是什么意思。你能详细说明一下吗?非常感谢。这取决于密码生成算法的实现。它基本上已经按照您的建议使用当前时间和当前状态重新设定PRNG每次呼叫的种子。请看我的答案。计数器宽度我的意思是,如果使用16位计数器,则只能计数到65535,否则32位计数器将给出2^32个组合,等等。因此,您需要确保计数器足够大,足以计算用户数。标题询问随机性,而内容询问唯一性。这些是完全不同的概念。@Tadeck感谢您的澄清,非常感谢@塔迪克:我完全不同意你的看法。这些并不是完全不同的概念。它们并排走。如果某些东西不够随机,那么就不能保证唯一性。我认为这个问题是有道理的。此外,你在这里提出的问题,如果你深入研究的话,这也是一个数学问题。@Patrickbasut:为了支持我的观点(随机性与唯一性是分开的),我建议你读一下:-它们可能更好地解释了差异。一个反对“如果某些东西不够随机,那么唯一性就无法保证”的例子是,这肯定不是随机的,并且每个项目都保证是唯一的(这就是为什么在许多RDBMS中经常使用它来保证主键的唯一性)。