nem*_*ign 6 django django-settings
我为openwisp2编写了一个ansible-role来简化其部署,它是一系列django应用程序.为了尽可能地简化部署,我写了一个简单的(可能是微不足道的)SECRET_KEY生成器脚本,由ansible调用,在第一次运行ansible playbook时生成密钥.
现在,这工作正常,但我认为它击败了Django生成一个很难猜的强键的内置安全措施.
当时我查看其他方法,但没有找到太多,现在我想知道:是否有一个函数用于生成django中的settings.SECRET_KEY?
这将避免这种家庭烘焙解决方案,即使它们工作,它们在安全性方面也无效.
Rik*_*eek 48
对于像我这样的懒人:
from django.core.management.utils import get_random_secret_key
get_random_secret_key()
Run Code Online (Sandbox Code Playgroud)
小智 20
我想补充一点,根据提交固定#31757 - 调整了 SECRET_KEY 的系统检查以警告自动生成的默认密钥,该方法get_random_secret_key()被认为是不安全的。
如果您使用的是 python 3.6+ 那么您可以使用该secrets.token_hex([nbytes=None])函数
python3 -c 'import secrets; print(secrets.token_hex(100))'
Run Code Online (Sandbox Code Playgroud)
TLDR信用:生成 Django 密钥
Dan*_*man 13
实际上,您可以使用在调用时生成新密钥的相同功能startproject,即django.core.management.utils.get_random_secret_key().
但请注意,它与您的版本没有太大差别.
hlo*_*ore 11
S Ghosh TLDR 引用的帖子:生成 Django 密钥表明,从版本 3.1.3 开始,Django 实际上secrets在幕后使用 Python 模块。看看这个 blob forget_random_secret_key和另一个 blob for get_random_string,我可以看到它是这样的:
def get_random_secret_key():
"""
Return a 50 character random string usable as a SECRET_KEY setting value.
"""
chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
return get_random_string(50, chars)
Run Code Online (Sandbox Code Playgroud)
def get_random_string(length, allowed_chars=RANDOM_STRING_CHARS):
"""
Return a securely generated random string.
The bit length of the returned value can be calculated with the formula:
log_2(len(allowed_chars)^length)
For example, with default `allowed_chars` (26+26+10), this gives:
* length: 12, bit length =~ 71 bits
* length: 22, bit length =~ 131 bits
"""
return ''.join(secrets.choice(allowed_chars) for i in range(length))
Run Code Online (Sandbox Code Playgroud)
正如我在代码中看到的,该函数的唯一问题get_random_secret_key是允许的字符不包含大写字母,因此相同大小的密钥的可能位数比包含大写字母时要小,但也不会太多:
from math import log2
lower_plus_numbers = (list(chr(o) for o in range(0x61, 0x7B))
+ list(chr(o) for o in range(0x30, 0x3A)))
punctuation = list('!@#$%^&*(-_=+)')
upper_alpha = list(chr(o) for o in range(0x41, 0x5B))
shorter = log2((len(lower_plus_numbers) + len(punctuation)) ** 50)
longer = log2((len(lower_plus_numbers) + len(punctuation) + len(upper_alpha)) ** 50)
print(f'longer: {int(longer + 0.5)}; shorter: {int(shorter + 0.5)} '
f'difference: {int(longer - shorter + 0.5)}; ratio: {longer/shorter}')
Run Code Online (Sandbox Code Playgroud)
上述代码的输出:
longer: 312; shorter: 282; difference: 30; ratio: 1.1070316647619918
Run Code Online (Sandbox Code Playgroud)
因此,如果您有足够新的 Django 和 Python,那么最大的问题是您是否想要生成SECRET_KEY依赖于 Dango 的版本,还是仅依赖于 Python。如果您不介意 Django 依赖性,但想要包含大写字母,或者想要更长的密钥,您可以轻松执行以下操作:
from django.utils.crypto import get_random_string
key_length = 60
get_random_string(
key_length,
allowed_chars=lower_plus_numbers + punctuation + upper_alpha,
)
Run Code Online (Sandbox Code Playgroud)
示例输出:
'gW(VDtylhoAuZNcLbIC=ai5=2*tPZ=Gmf4D1^4T!NxX3tB0%_w7pYY2+FgDx'
Run Code Online (Sandbox Code Playgroud)
如果您不想要 Django 依赖项,您可以使用 S Ghosh 的答案。或者,如果您想要的不仅仅是十六进制字符,您可以执行以下操作:
allowed_chars = [chr(i) for i in range(0x21, 0x7F)]
key_length = 60
key = ''.join(secrets.choice(allowed_chars) for i in range(key_length))
Run Code Online (Sandbox Code Playgroud)
值key(作为 python 字符串):
'DN7tbWid#q6R^=%i"[1AA>$@AZg=XD+p|[aB?:#V`:kKWL77P6dC,~(\\9O\'j'
Run Code Online (Sandbox Code Playgroud)
在终端上运行以下命令。
$ python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'
Run Code Online (Sandbox Code Playgroud)
输出:
2x$e%!k_u_0*gq0s4!_u(2(^lpy&gir0hg)q&5nurj0-sseuav
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1381 次 |
| 最近记录: |