改变Django的SECRET_KEY的影响

Der*_*wok 184 django

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

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

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

sbe*_*der 186

编辑:这个答案是基于django 1.5

SECRET_KEY 我会在很多不同的地方使用它,我会首先指出它受到什么影响,然后尝试查看该列表并准确解释其影响.

SECRET_KEY直接或间接使用的事物列表:

在现实中有很多在这里列出的项目中使用SECRET_KEYdjango.utils.crypt.get_random_string()它使用它来播种随机引擎.这不会受到价值变化的影响SECRET_KEY.

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

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

更新:现在正在研究django 1.9.5,快速查看源代码给出了几乎相同的答案.以后可能会进行彻底的检查.

  • @Henning我不这么认为.[密码存储](https://docs.djangoproject.com/en/dev/topics/auth/passwords/)作为auth_user中的`<algorithm> $ <iterations> $ <salt> $ <hash>`,所以在每种情况下,随机盐与密码一起存储. (5认同)
  • 我正在我的本地开发服务器上更改 SECRET_KEY 并且这不会让我注销,所以看起来至少会话(缓存)在更改后可以正常工作。您能否进一步详细说明“数据解码将中断”的含义,并指出一些会中断的代码(在 django 或示例项目中)?编辑:仍在使用 django 1.4 - 是这样吗? (2认同)
  • 对于Django版本> 1.5,答案会有明显的不同吗?(例如现在的1.9) (2认同)

Don*_*kby 32

自从提出这个问题以来,Django文档已经改为包含一个答案.

密钥用于:

  • 如果您正在使用任何其他会话后端django.contrib.sessions.backends.cache,或正在使用默认会话,则为所有会话get_session_auth_hash().
  • 所有消息,如果您正在使用CookieStorageFallbackStorage.
  • 所有PasswordResetView代币.
  • 除非提供不同的密钥,否则使用加密签名.

如果您旋转密钥,上述所有内容都将失效.密钥不用于用户密码,密钥轮换不会影响它们.

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

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
Run Code Online (Sandbox Code Playgroud)

更新

看起来Django 在版本1.10中添加了该get_random_secret_key()功能.您可以使用它来生成新的密钥.

$ ./manage.py shell -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
s!)5@5s79sp=92a+!f4v!1g0d0+64ln3d$xm1f_7=749ht&-zi
$ ./manage.py shell -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
_)+%kymd=f^8o_fea1*yro7atz3w+5(t2/lm2cz70*e$2mn\g3
$
Run Code Online (Sandbox Code Playgroud)

  • 嘿,对不起,@ DonKirkby,恶作剧 (10认同)
  • 密钥生成是否依赖于密钥? (4认同)
  • 不,@ kdazzle,如果你看一下[startproject`的源代码](https://github.com/django/django/blob/1.8.6/django/core/management/commands/startproject.py#L31 ),你可以看到它只是使用`crypto`模块生成一个随机字符串. (4认同)

Tim*_*ing 16

根据这个页面https://docs.djangoproject.com/en/dev/topics/signing/,SECRET_KEY主要用于短暂的东西 - 签署通过网络发送的数据,以便您可以检测到篡改.它看起来像可能破坏的东西:

  • 签名的cookie,例如"记住我在此计算机上的身份验证"类型值.在这种情况下,cookie将无效,签名将无法验证,用户将不得不重新进行身份验证.
  • 对于已请求密码重置或自定义文件下载链接的任何用户,这些链接将不再有效.用户只需重新请求这些链接.

与我相比具有更新近和/或显着的Django经验的人可能会引发其他问题,但我怀疑除非您明确使用签名API执行某些操作,否则这应该只会给您的用户带来轻微的不便.

  • 那么为什么不在每次服务器重启时生成新密钥? (6认同)
  • 如果您使用多个进程运行相同的服务器,则可能会导致问题. (3认同)
  • @osa你想在每次推送代码/重新启动服务器时注销所有用户吗? (3认同)

dar*_*ess 6

SECRET_KEY字符串主要用于加密和/或哈希Cookie数据。因为默认的会话cookie有其自身的缺点,所以很多框架(包括Django)都可以做到这一点。

想象一下,您在django中具有用于编辑带有隐藏字段的文章的表单。在此隐藏字段中存储了您正在编辑的文章的ID。而且,如果您要确保没有人可以向您发送其他任何文章ID,您将添加一个带有哈希ID的额外隐藏字段。因此,如果有人更改ID,您将知道它,因为哈希值不会相同。

当然,这是一个简单的示例,但这就是SECRET_KEY的使用方式。

Django内部使用它,例如用于{%csrf_token%}和其他一些东西。如果您根据自己的问题并且未使用它来进行更改,那么它实际上不会对您的应用程序产生任何影响。

唯一的是,可能会删除会话值。因此,例如,用户将不得不再次登录admin,因为django将无法使用其他密钥来解码会话。