更改Django的SECRET_KEY的影响

我犯了一个错误,并将我的Django项目的SECRET_KEY提交到公共存储库。

根据文档https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-SECRET_KEY应该保密

Django项目是实时的,并且已经与一些活跃的用户一起运行了一段时间。 如果我改变SECRET_KEY什么影响? 任何现有的用户,cookies,会话等会受到影响吗? 显然,新的SECRET_KEY将不再存储在公共场所。

编辑:这个答案是基于Django的1.5

SECRET_KEY被用在很多不同的地方,我会首先指出它受到的影响,然后试着去查看这个列表,并且给出精确的解释。

直接或间接使用SECRET_KEY的事物清单:

  • JSON对象签名
  • encryption hmacs function或种子的随机引擎,影响:
    • 密码重置令牌
    • 注释表单安全性以防止伪造的POST请求
    • 形成安全
    • 防止消息篡改,因为消息框架可能使用cookie在视图之间传递消息。
    • 保护会话数据并创build随机会话密钥以避免篡改。
    • 为大多数密码哈希创build随机盐
    • 必要时创build随机密码
    • 在使用startproject时创build自己
    • 创buildCSRF密钥

实际上,这里列出的很多项目都是通过django.utils.crypt.get_random_string()使用SECRET_KEY来使用它来为随机引擎播种。 这不会受到SECRET_KEY值的改变的影响。

直接受价值变化影响的用户体验如下:

  • 会话,数据解码将会中断,这对于任何会话后端(cookie,数据库,基于文件或caching)都是有效的。
  • 已经发送的密码重置令牌将不起作用,用户将不得不问一个新的。
  • 注释表单(如果使用django.contrib.comments )将不会validation是否在值更改之前请求它,并在值更改后提交。 我认为这是非常小的,但可能会让用户感到困惑。
  • 消息(来自django.contrib.messages )不会在与注释表单相同的时间条件下validation服务器端。

更新 :现在在Django 1.9.5上工作,快速查看源代码给了我几乎相同的答案。 以后可能会做一个彻底的检查。

根据这个页面https://docs.djangoproject.com/en/dev/topics/signing/,SECRET_KEY主要用于暂时的东西; – 签名通过电线发送的数据,所以你可以检测到篡改,例如。 看起来可能会破碎的是:

  • 签名的cookies,例如“记住我在这台电脑上的validation”types的值。 在这种情况下,cookie将失效,签名将无法validation,用户将不得不重新进行身份validation。
  • 对于任何请求链接进行密码重置或自定义文件下载的用户,这些链接将不再有效。 用户只需要重新请求这些链接。

有人比我更近期和/或突出Django的经验可能会有其他声音,但我怀疑,除非你明确地做了一些与签名的API,这只会给你的用户造成轻微的不便。

由于这个问题被问到, Django文档已经改变,以包括一个答案。

密钥用于:

  • 所有会话,如果您使用任何其他会话后端比django.contrib.sessions.backends.cache ,或者如果您使用SessionAuthenticationMiddleware并使用默认的get_session_auth_hash()
  • 所有消息,如果您使用CookieStorageFallbackStorage
  • 使用cookie存储与formtools.wizard.views.CookieWizardView时,表单向导进度。
  • 所有password_reset()令牌。
  • 所有正在进行的预览。
  • 任何使用encryption签名的情况,除非提供了不同的密钥。

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

我不清楚我应该如何旋转密钥。 我find了关于Django如何为新项目生成密钥的讨论,以及讨论其他选项的Gist。 我最终决定让Django创build一个新项目,将新密钥复制到我的旧项目中,然后删除新项目

 cd ~/junk # Go to some safe directory to create a new project. django-admin startproject django_scratch grep SECRET_KEY django_scratch/django_scratch/settings.py # copy to old project rm -R django_scratch 

SECRET_KEYstring主要用于encryption和/或散列cookies数据。 很多框架(包括Django)都是这样做的,因为默认会话cookie有它自己的缺点。

想象一下你在django中有一个用隐藏字段编辑文章的窗体。 在这个隐藏字段中存储了您正在编辑的文章的ID。 如果你想确保没有人可以给你任何其他的文章ID,你会添加一个额外的隐藏字段哈希ID。 所以如果有人会改变ID,你会知道它,因为哈希将不会是相同的。

当然这是一个微不足道的例子,但这是SECRET_KEY的使用方法。

Django是内部使用它为例如{%csrf_token%}和更less的东西。 如果您将根据您的问题进行更改,并且您没有使用它,那么对您的应用程序确实不应该有任何影响。

唯一可能的是会话值将被丢弃。 因此,例如,用户将不得不再次login到pipe理员,因为Django将无法使用不同的密钥解码会话。