更改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()
。- 所有消息,如果您使用
CookieStorage
或FallbackStorage
。- 使用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将无法使用不同的密钥解码会话。