更改Django的SECRET_KEY

nfeuvbwi  于 2023-05-01  发布在  Go
关注(0)|答案(6)|浏览(227)

我犯了一个错误,把我的Django项目的SECRET_KEY提交到了一个公共仓库。
根据文档,此密钥应该保密。
Django项目已经上线,并且已经有一些活跃用户运行了一段时间。如果我改变SECRET_KEY会有什么影响?将任何现有用户、cookie、会话等.受到影响?显然,新的SECRET_KEY将不再存储在公共位置。

oxalkeyp

oxalkeyp1#

编辑:这个答案基于django 1。5
SECRET_KEY被用在很多不同的地方,我将首先指出它会影响什么,然后尝试查看该列表并给予准确的影响解释。
直接或间接使用SECRET_KEY的事物列表:

实际上,这里列出的很多项目都使用SECRET_KEYdjango.utils.crypt.get_random_string(),它们使用它来播种随机引擎。这不会受到SECRET_KEY值变化的影响。
直接受价值变化影响的用户体验包括:

  • 会话时,数据解码将中断,这对任何会话后端(cookie、数据库、基于文件或缓存)都有效。
  • 已经发送的密码重置令牌将不起作用,用户将不得不要求一个新的。
  • 注解表单(如果使用django.contrib.comments)将不会验证是否在值更改之前请求并在值更改之后提交。我认为这是非常小的,但可能会混淆用户。
  • 消息(来自django.contrib.messages)不会在与注解表单相同的时间条件下验证服务器端。
    更新:现在正在使用django 1。9.5,快速浏览源代码给我几乎相同的答案。稍后可能会做一个彻底的检查。
bvn4nwqk

bvn4nwqk2#

自从这个问题被提出以来,Django文档已经改变,包括一个答案。
密钥用于:

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

如果你轮换你的密钥,以上所有的都将失效。密钥不用于用户的密码,密钥轮换也不会影响用户的密码。
我并不清楚该如何旋转密钥。我发现了一个关于Django generates a key for a new project如何的讨论,以及一个讨论other options的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

更新

看起来Django在版本1中添加了get_random_secret_key()函数。10.你可以用它来生成一个新的密钥。

$ ./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
$
hl0ma9xz

hl0ma9xz3#

根据https://docs.djangoproject.com/en/dev/topics/signing/页面,SECRET_KEY主要用于临时性的东西--例如,对通过线路发送的数据进行签名,以便您可以检测篡改。看起来可能会被打破的东西是:

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

一些比我更新和/或更突出的Django经验的人可能会插话,但我怀疑除非你明确地使用签名API做一些事情,否则这只会给你的用户带来轻微的不便。

yeotifhr

yeotifhr4#

SECRET_KEY字符串主要用于加密和/或散列cookie数据。许多框架(包括Django)都是这样做的,因为默认的会话cookie有自己的缺点。
假设你在django中有一个表单,可以编辑带有隐藏字段的文章。在这个隐藏字段中存储了您编辑的文章的ID。如果你想确保没有人可以向你发送任何其他的文章id,你需要添加一个额外的隐藏字段与hashed id。因此,如果有人更改了ID,您将知道它,因为哈希值将不相同。
当然,这是一个简单的例子,但这是如何使用SECRET_KEY的。
Django在内部使用它,例如{% csrf_token %}和其他一些东西。如果您根据您的问题更改它,并且您没有使用它,那么它真的不应该对您的应用程序有任何影响。
唯一的事情是可能会话值将被删除。例如,用户将不得不再次登录admin,因为django将无法解码具有不同密钥的会话。

uinbv5nw

uinbv5nw5#

我也犯了同样的错误。默认密码长度为50,所以我使用powershell生成了一个50长的随机字符串,并用它替换了旧的SECRET_KEY。我登录后,更换SECRET_KEY我以前的会话已失效.
Powershell(source):

# Load the .net System.Web namespace which has the GeneratePassword function
[Reflection.Assembly]::LoadWithPartialName("System.Web")

#  GeneratePassword(int length, int numberOfNonAlphanumericCharacters)
[System.Web.Security.Membership]::GeneratePassword(50,5)

使用Bash(source):

# tr includes ABCabc123 and the characters from OWASP's "Password special characters list"
cat /dev/urandom | tr -dc 'A-Za-z0-9!"#$%&\''()*+,-./:;<=>?@[\]^_`{|}~' | head -c 100 ; echo

在这一点上我想为什么不尝试一个更大的关键,所以我尝试了它与100和1000长的关键。两个都奏效了。如果我理解了源代码,signer函数返回的对象是base64中的hmac哈希。RFC 2104对HMAC密钥所需的长度有这样的规定。
使用长于B字节的密钥的应用程序将首先使用H对密钥进行散列,然后使用得到的L字节字符串作为HMAC的实际密钥。
HMAC的密钥可以是任意长度(长于B字节的密钥首先使用H散列)。然而,强烈不鼓励小于L字节,因为这会降低函数的安全强度。长于L字节的密钥是可接受的,但额外的长度不会显著增加功能强度。(如果密钥的随机性被认为是弱的,则更长的密钥可能是可取的。)
为了转换成正常说法,密钥的大小需要与输出大小相同。密钥也需要以比特为单位。base64中的每个数字代表6位。所以如果你有一个50个字符的密码,你将有一个50 x 6 = 300位的密钥。如果你使用的是SHA 256,那么你需要一个256位的密钥(* sha 256使用256位的定义 *)。因此,50长的密码应该有效,除非您计划使用大于SHA 256的哈希算法。
但是由于密钥中的任何额外位都被散列,因此它的大小不会大幅降低性能。但它可以保证你有足够的位来处理更大的哈希函数。SHA-512将由100长的SECRET_KEY(*50 x 6 = 600位〉512位 *)覆盖。

r6vfmomb

r6vfmomb6#

安装django-extensions:

pip install django-extensions

您需要将django_extensions应用程序添加到Django项目www. example的INSTALLED_APPS设置中 www.example.com 文件:

INSTALLED_APPS = (
    ...
    'django_extensions',
)

创建一个新的密钥,您可以将其放入 www.example.com

python manage.py generate_secret_key

相关问题