【问题标题】:How to generate passwords in Python 2 and Python 3? Securely?如何在 Python 2 和 Python 3 中生成密码?安全吗?
【发布时间】:2017-06-17 13:39:42
【问题描述】:

在 Stackoverflow 上至少有一篇与此主题相关的帖子:Generate password in python

你会发现这个话题甚至在 PEP 中也受到了一些批评。这里提到了:https://www.python.org/dev/peps/pep-0506/

那么,如何在 Python 2 和 Python 3 中正确安全地生成随机密码?

【问题讨论】:

标签: python python-3.x security random cryptography


【解决方案1】:

Python 2

您可能知道,Python 2 中的 random 模块使用不安全的伪随机数生成器。这在官方文档页面的警告中明确说明:“此模块的伪随机生成器不应用于安全目的。”

random 模块是不安全的,因为它的内部结构依赖于主机上当前时间播种的算法(Mersenne Twister 算法)。尽管具有良好的输出统计特性,但此类算法的输出具有高度可预测性,并且容易受到随机数生成器攻击。如果您不相信安全专业人士,请查看这篇热门帖子:https://jazzy.id.au/2010/09/22/cracking_random_number_generators_part_3.html

Python 2 的官方文档推荐使用os.urandom 函数和SystemRandom 类,因为它们使用操作系统提供的更安全的随机数源。

操作系统使用来自多个来源的数据生成伪随机数,其中大多数是非常不可预测的并且具有高熵。 Linux 上的os.urandom 使用来自/dev/urandom 设备的输出。您可以查看官方内核文档以获取有关/dev/urandom 的详细信息以及与/dev/random 的差异。另外,如果您使用硬件随机数生成器,是否可以将其用作/dev/random

Python 2 中这个问题的答案可能如下所示:

import os

def gen_password(length=8, charset="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()"):
    random_bytes = os.urandom(length)
    len_charset = len(charset)
    indices = [int(len_charset * (ord(byte) / 256.0)) for byte in random_bytes]
    return "".join([charset[index] for index in indices])

Python 3

最新的 Python 3.6 有一个名为 secrets 的模块。在corresponding PEP-0506 by Steven D'Aprano 中提出。该模块的目的是提供适用于现代应用程序和“密码天真”用户的“默认安全”密码原语。它还为加密内容提供了简洁明了的 API。

考虑以下在 Python 3 中生成随机密码的实现。

import secrets

def gen_password(length=8, charset="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()"):
    return "".join([secrets.choice(charset) for _ in range(0, length)])

【讨论】:

  • 在 Python 2 上,您还可以使用 SystemRandom,它在后台使用 urandom,但公开了 .choice() 方法,因此您可以像 Python 3 示例一样编写单行代码。 docs.python.org/2/library/random.html#random.SystemRandom
  • 另外,对于 Python 2 和 3,.join() 可以使用生成器表达式而不是列表来调用。语法会干净一点,代码运行速度会更快:"".join(secrets.choice(charset) for _ in range(length))
猜你喜欢
  • 2021-07-05
  • 2016-05-28
  • 1970-01-01
  • 2011-04-20
  • 2021-03-29
  • 2011-03-16
  • 2014-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多