我犯了一个错误,并将我的Django项目SECRET_KEY
提交到公共存储库。
根据文档https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-SECRET_KEY
,该密钥应该保密 Django项目正在运行,并且已经与一些活跃用户运行了一段时间。如果我更改SECRET_KEY
会有什么影响?任何现有用户,cookie,会话等都会受到影响吗?显然,新的SECRET_KEY
将不再存储在公共场所。
答案 0 :(得分:172)
编辑:此答案基于django 1.5
SECRET_KEY
用于很多不同的地方,我会首先指出它受到什么影响,然后尝试查看该列表并准确解释其影响。
直接或间接使用SECRET_KEY
的事项列表:
startproject
实际上,此处列出的很多项目使用SECRET_KEY
到django.utils.crypt.get_random_string()
,它使用它来为随机引擎播种。这不会受到SECRET_KEY
的价值变化的影响。
直接受价值变化影响的用户体验是:
django.contrib.comments
)将不会验证是否在值更改之前请求并在值更改后提交。我认为这是非常小的,但可能会让用户感到困惑。django.contrib.messages
)不会在与评论表单相同的时间条件下验证服务器端。更新:现在正在研究django 1.9.5,快速浏览一下源代码,给出了几乎相同的答案。以后可能会进行彻底检查。
答案 1 :(得分:26)
自提出此问题以来,Django documentation已更改为包含答案。
密钥用于:
- 如果您使用的是
get_session_auth_hash()
以外的任何其他会话后端,或者使用的是默认CookieStorage
,则- 所有会话。
- 如果您使用的是
FallbackStorage
或PasswordResetView
,则会收到所有消息。- 所有
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 generates a key for a new project的讨论以及讨论other options的要点的讨论。我最终决定让Django创建一个新项目,将新的密钥复制到我的旧项目中,然后擦除新项目。
$ ./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
$
看起来Django在版本1.10中添加了get_random_secret_key()
function。您可以使用它来生成新的密钥。
<ScrollView
android:id="@+id/SView"
android:layout_below="@id/tvNama"
android:layout_marginBottom="25dp"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="@+id/sound">
<FrameLayout
android:id="@+id/scroll_view_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:id="@+id/tvketerangan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="keterangan"
android:textStyle="bold"
android:textColor="#000000"
android:textSize="16sp"/>
<ImageView
android:id="@+id/imageview"
android:layout_width="300dp"
android:layout_height="300dp"
android:src="@drawable/sa"
android:layout_below="@+id/tvketerangan"
android:layout_centerHorizontal="true"/>
</FrameLayout>
</ScrollView>
答案 2 :(得分:16)
根据这个页面https://docs.djangoproject.com/en/dev/topics/signing/,SECRET_KEY主要用于暂时性的东西 - 签署通过网络发送的数据,以便您可以检测到篡改。看起来可能会破坏的东西是:
有一些比我更近期和/或显着的Django经验的人可能会反感,但我怀疑除非你明确地使用签名API做一些事情,否则这只会给你的用户带来轻微的不便。
答案 3 :(得分:5)
SECRET_KEY字符串主要用于加密和/或散列cookie数据。由于默认会话cookie有其自身的缺点,因此很多框架(包括Django)都会出现这种情况。
想象一下,你在django中有表格用于编辑带有隐藏字段的文章。在此隐藏字段中存储您已编辑的文章的ID。如果您想确保没有人可以向您发送任何其他文章ID,您将添加一个带有散列ID的额外隐藏字段。因此,如果有人会更改ID,您就会知道它,因为哈希值不会相同。
当然这是一个简单的例子,但这就是使用SECRET_KEY的方式。
Django正在使用它作为例如{%csrf_token%}以及更多的东西。如果您根据自己的问题进行更改并且不使用它,那么它对您的应用程序确实不会产生任何影响。
唯一的问题是可能会话值将被删除。因此,例如用户将不得不再次登录管理员,因为django将无法使用不同的密钥解码会话。
答案 4 :(得分:0)
我犯了同样的错误。默认密码为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长的键。两者都起作用。如果我了解source code,则签名者函数返回的对象是base64中的hmac哈希。 RFC 2104的意思是HMAC密钥的所需长度。
使用键的时间更长的应用程序 比B字节先使用H哈希密钥,然后使用 所得的L字节字符串作为HMAC的实际密钥。
HMAC的密钥可以是任何长度(大于B字节的密钥是 首先使用H进行哈希处理)。但是,强烈建议少于L个字节 不鼓励这样做,因为这会降低安全性 功能。长度超过L个字节的密钥是可以接受的,但是额外的 长度不会显着增加功能强度。 (一种 如果密钥的随机性是 被认为是弱者。)
要翻译成普通话,密钥的大小必须与输出大小相同。密钥也需要以位为单位。 base64中的每个数字代表6位。因此,如果您拥有50个字符的密码,那么您将拥有一个50 x 6 = 300位的秘密密钥。如果使用SHA256,则需要一个256位密钥( sha256根据定义使用256位)。因此,除非您打算使用大于SHA256的哈希算法,否则50个长的密码应该可以工作。
但是由于密钥中的任何多余位都被散列,因此其大小不会显着降低性能。但这可以保证您有足够的位数用于较大的哈希函数。 SHA-512可以覆盖100个长的SECRET_KEY( 50 x 6 = 600位> 512位)。