Django 设置“SECRET_KEY”的目的是啥?

Posted

技术标签:

【中文标题】Django 设置“SECRET_KEY”的目的是啥?【英文标题】:What's the purpose of Django setting ‘SECRET_KEY’?Django 设置“SECRET_KEY”的目的是什么? 【发布时间】:2011-11-14 23:29:28 【问题描述】:

我进行了一些谷歌搜索并查看了文档 (https://docs.djangoproject.com/en/dev/ref/settings/#secret-key),但我一直在寻找对此进行更深入的解释,以及为什么需要它。

例如,如果密钥被泄露/其他人知道它是什么,会发生什么?

【问题讨论】:

如果您有一个密钥,并且它被泄露并泄露给了其他人,那么您就有问题了。不管你是否使用 Django。 但是到底有什么问题? 我做了彻底的回答here(无耻塞) @sberder 也许你也应该写一个这个问题的答案。我想你可以比接受的不回答做得更好。 【参考方案1】:

它用于制作哈希。看:

>grep -Inr SECRET_KEY *
conf/global_settings.py:255:SECRET_KEY = ''
conf/project_template/settings.py:61:SECRET_KEY = ''
contrib/auth/tokens.py:54:        hash = sha_constructor(settings.SECRET_KEY + unicode(user.id) +
contrib/comments/forms.py:86:        info = (content_type, object_pk, timestamp, settings.SECRET_KEY)
contrib/formtools/utils.py:15:    order, pickles the result with the SECRET_KEY setting, then takes an md5
contrib/formtools/utils.py:32:    data.append(settings.SECRET_KEY)
contrib/messages/storage/cookie.py:112:        SECRET_KEY, modified to make it unique for the present purpose.
contrib/messages/storage/cookie.py:114:        key = 'django.contrib.messages' + settings.SECRET_KEY
contrib/sessions/backends/base.py:89:        pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest()
contrib/sessions/backends/base.py:95:        if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
contrib/sessions/backends/base.py:134:        # Use settings.SECRET_KEY as added salt.
contrib/sessions/backends/base.py:143:                       settings.SECRET_KEY)).hexdigest()
contrib/sessions/models.py:16:        pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest()
contrib/sessions/models.py:59:        if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
core/management/commands/startproject.py:32:        # Create a random SECRET_KEY hash, and put it in the main settings.
core/management/commands/startproject.py:37:        settings_contents = re.sub(r"(?<=SECRET_KEY = ')'", secret_key + "'", settings_contents)
middleware/csrf.py:38:                % (randrange(0, _MAX_CSRF_KEY), settings.SECRET_KEY)).hexdigest()
middleware/csrf.py:41:    return md5_constructor(settings.SECRET_KEY + session_id).hexdigest()

【讨论】:

当时为什么不叫它盐呢? ;) 这是一个猜测,但我想告诉人们“不要分享你的 SECRET_KEY”,而不是“你的 SALT 是一个你应该保留的秘密密钥”更容易自己。” 这种区别非常重要。在密码学中,盐不是秘密的,但SECRET_KEY 必须保持安全。 SECRET_KEY 的使用更类似于在 HMAC 等签名哈希中使用密钥(如果不考虑性能,可能会使用它)。 这看起来不像是我的答案。您所做的只是一个 grep 命令,而没有解释它的作用。 “如果密钥被泄露会发生什么?”的答案在哪里? 此外,由于 SECRET_KEY 是机密的,在密钥前加上 SECRET 前缀可确保 Django 将在需要时加密/屏蔽值。【参考方案2】:

Django documentation for cryptographic signing 涵盖了“SECRET_KEY”设置的使用:

此值 [SECRET_KEY 设置] 是保护签名数据的关键 - 确保此值的安全至关重要,否则攻击者可能会使用它来生成自己的签名值。

(此部分也引用自the Django documentation for the ‘SECRET_KEY’ setting。)

Django 中的加密签名 API 可用于任何应用程序,用于对值进行加密安全签名。 Django 本身在各种更高级别的功能中使用了这一点:

Signing serialised data(例如 JSON 文档)。

用于用户会话、密码重置请求、消息等的唯一令牌。

通过为请求添加(然后预期)唯一值来防止跨站点或重放攻击。

为散列函数生成唯一盐。

所以,一般的答案是:Django 应用程序中有很多东西需要加密签名,而“SECRET_KEY”设置是用于这些的密钥。它需要在所有 Django 实例之间具有加密强度高的熵(计算机难以猜测)并且是唯一的。

【讨论】:

"并且在所有 Django 实例之间是唯一的。" -- 这是否意味着如果说我有 3 个网络服务器在负载均衡器后面运行相同的 Django 应用程序,我应该有 3 个不同的 SECRET_KEY 设置? @AdamParkin,对于a new question 来说,这听起来像是一个很好的开始,可以得到自己的答案。 伟大的建议,完成:***.com/questions/51657422/…【参考方案3】:

According to the Django Documentation on SECRET_KEY:

密钥用于:

如果您使用除 django.contrib.sessions.backends.cache 之外的任何其他会话后端,或者使用默认的 get_session_auth_hash(),则所有会话。 如果您使用的是 CookieStorageFallbackStorage 的所有消息。 所有 PasswordResetView 令牌。 加密签名的任何使用,除非提供不同的密钥。

如果您轮换您的密钥,以上所有内容都将失效。密钥不用于用户密码,密钥轮换不会影响他们。

【讨论】:

关于SECRET_KEY 旋转时会发生什么的有用信息。 +1

以上是关于Django 设置“SECRET_KEY”的目的是啥?的主要内容,如果未能解决你的问题,请参考以下文章

SECRET_KEY 设置不能为空 - django+pycharm

Django:配置不当:SECRET_KEY 设置不能为空

django.core.exceptions.ImproperlyConfigured:设置 SECRET_KEY 环境变量

将环境变量中的 Django SECRET_KEY 传递给 Dockerized gunicorn

在 miniconda 环境中隐藏 django secret_key 时出错

Django SECRET KEY 错误