在 Python 中生成密码的安全问题?
我已经阅读了一些关于以编程方式生成密码的不同帖子,很多人都评论说使用标准随机模块存在安全风险.有人可以解释为什么吗?如果我使用标准随机库来选择 20 个随机字符/符号/数字来生成密码,那么这肯定比您妈妈或爸爸可能拥有的许多常规"密码强得多?
I've read a few different posts about generating passwords programatically, and many have comments from people saying using standard random module is a security risk. Can someone explain why? If I am using the standard random library to select 20 random characters/symbols/numbers to generate a password, surely this is far stronger than many 'regular' passwords your mom or dad might have?
我知道这不是真正的随机,但我看不出在这个用例中这有什么问题.
I understand that it's not true random, but I can't see how that's an issue in this use case.
这取决于标准随机库"的含义.
It depends on what is meant by the "standard random library".
Python 提供了两者——
Python provides both—
- 非加密伪随机生成器(除
random.SystemRandom
外的所有random
模块),其设计不用于安全应用,包括生成秘密值,以及 - 加密随机生成器(
random.SystemRandom
或secrets
模块), 专为安全用途而设计.
- A noncryptographic pseudorandom generator (all of the
random
module exceptrandom.SystemRandom
), which is not designed for use in security applications, including to generate secret values, and - a cryptographic random generator (
random.SystemRandom
or thesecrets
module), which is designed for security use.
以及 secrets
模块的文档 明确表示它会生成适合管理密码、帐户身份验证、安全令牌和相关机密等数据的加密强随机数",并包括用于生成强随机密码的代码示例.加密强随机数"的通常要求是他们应该很难被外部攻击者猜到.为此,secrets
模块可能依赖于操作系统提供的随机数生成器(例如,secrets.SystemRandom
就是这样做的).
And the documentation for the secrets
module clearly says it produces "cryptographically strong random numbers suitable for managing data such as passwords, account authentication, security tokens, and related secrets", and includes a code example for generating a strong random password. A usual requirement for "cryptographically strong random numbers" is that they should be hard to guess by outside attackers. To this end, the secrets
module may rely on the random number generator provided by the operating system (as secrets.SystemRandom
does, for example).
另一方面,非加密伪随机数生成器(例如 Mersenne Twister,它是大多数 random
模块使用的生成器)是为统计质量而设计的,而不是生成难以-猜数字.
On the other hand, a noncryptographic pseudorandom number generator (such as Mersenne Twister, which is the generator used by most of the random
module) is designed for statistical quality rather than generating hard-to-guess numbers.
在安全应用中:
- 使用
secrets
模块或random.SystemRandom
(而不是random
模块的其余部分)生成随机字符串,用作密码、不记名凭证、随机数、会话标识符、验证码"或确认码",或另一个秘密值.例如,secrets.token_hex
方法生成一个可读的随机字符串,设计为难以猜测. - 一般来说,密码不应存储在任何地方,即使是加密或混洗,除非它们被散列";和盐渍".加盐散列是对密码的不可逆操作,无法仅通过知道输出来恢复原始密码.不幸的是,
secrets
模块没有提供任何东西可以帮助您以安全的方式散列密码,而不仅仅是生成密码.
- Use the
secrets
module orrandom.SystemRandom
(rather than the rest of therandom
module) to generate random strings that will serve as a password, a bearer credential, a nonce, a session identifier, a "verification code" or "confirmation code", or another secret value. For example, thesecrets.token_hex
method generates a readable random string designed to be hard to guess. - In general, passwords should not be stored anywhere, even encrypted or shuffled, unless they're "hashed" and "salted". Salted hashing is an irreversible operation on passwords that renders it impossible to recover the original password by knowing just the output. Unfortunately, the
secrets
module provides nothing that will help you hash passwords in a secure way, as opposed to just generating them.