是否有一个在django中生成settings.SECRET_KEY的函数?

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)

  • 这个解决方案是在后面使用python的secrets lib,所以,很酷!你可以在Django的crypto.py文件中找到它[链接](https://github.com/django/django/blob/bfe9665502c77baf14ce6cf52af974033bd43164/django/utils/crypto.py#L62):`return ''.join(secrets.选择(allowed_chars) for i in range(length))` (3认同)
  • “请注意,这对于生产来说可能不安全,正如 S Ghosh 在下面的帖子中指出的那样。” - 从标签版本 3.1.3 `get_random_secret_key` 开始使用 Secrets 模块 (3认同)

小智 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().

但请注意,它与您的版本没有太大差别.

  • @Psddp你可以这样做,但这意味着每次你的应用程序启动/重新启动时,你都会得到一个新的密钥,这意味着所有现有的会话、cookie等都将失效。如果这不是您使用或关心的东西,那么这可以工作,但仍然感觉不应该这样做。 (5认同)

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)


Riz*_*ufi 7

在终端上运行以下命令。

$ 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)