Django 设置 'SECRET_KEY' 的目的是什么?

256

8
如果你有一把密钥,但它已经被泄露给他人,那么你会面临问题。无论你是否正在使用Django框架都是如此。 - Jared Farrish
75
确切地说,是什么问题? - tobych
13
我在这里进行了详细回答(无耻地自荐)。 - sberder
5
@sberder,也许你也应该回答这个问题。我想你可以比被接受的非回答者做得更好。 - kasperd
3个回答

132

它用于生成哈希值。看下面:

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

27
那他们为什么不直接称它为盐呢?;) - datenwolf
51
这只是一种猜测,但我认为告诉别人“不要分享你的SECRET_KEY”比“你的SALT是一个需要保密的密钥”更容易让人理解。 - Roshan Mathews
20
这个区分非常重要。在密码学中,盐并不是秘密,但必须保持SECRET_KEY的安全。使用SECRET_KEY更类似于在签名哈希(例如HMAC)中使用密钥,这种情况下,密钥必须保密(如果性能不是考虑因素,可能会使用HMAC)。 - Travis Jensen
61
这个回答对我来说看起来并不是一个完整的答案。你只是列出了一个grep命令,但没有解释它的任何内容。那么,“如果密钥被泄漏会发生什么”这个问题的答案在哪里呢? - kasperd
1
它不用于密码。密码使用每个帐户的随机生成盐和默认的PKGF哈希。但它用于其他东西,比如生成密码重置链接等等。https://github.com/django/django/blob/main/django/contrib/auth/hashers.py#L206 https://github.com/django/django/blob/main/django/contrib/auth/hashers.py#L280 - Marat Mkhitaryan
显示剩余3条评论

85

Django加密签名文档介绍了如何使用“SECRET_KEY”设置:

这个值[即“SECRET_KEY”设置]是保护签名数据的关键 - 您必须确保它安全,否则攻击者可能会使用它来生成自己的签名值。

(此部分还可以从“SECRET_KEY”设置的Django文档中引用。)

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

  • 签名序列化数据(例如JSON文档)。

  • 为用户会话、密码重置请求、消息等生成唯一令牌。

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

  • 生成哈希函数的唯一盐值。

因此,一般的答案是:Django应用程序中有许多需要进行加密签名的事情,“SECRET_KEY”设置是用于这些事情的关键。它需要具有密码安全的熵量(难以让计算机猜测),并且在所有Django实例之间是唯一的。


2
“and unique between all Django instances.”这句话是否意味着,如果我有3个运行相同Django应用程序的Web服务器在负载均衡器后面,我应该有3个不同的SECRET_KEY设置? - Adam Parkin
3
@AdamParkin,这听起来是一个好的开始提出新问题,以获得自己的答案。 - bignose
2
很好的建议,已完成:https://dev59.com/8VUK5IYBdhLWcg3wjgft - Adam Parkin
1
这应该是被接受的答案。第一个答案含糊不清。 - undefined

49

根据Django文档中对SECRET_KEY的说明

秘密密钥用于以下内容:

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

如果您旋转秘密密钥,则上述所有内容都将无效。秘密密钥不用于用户密码,密钥旋转不会影响它们。


16
如果SECRET_KEY被轮换,以下是有用的信息。+1 - Hassan Baig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接