장고의 SECRET_KEY 변경 효과


202

실수를해서 장고 프로젝트 SECRET_KEY를 공공 저장소에 맡겼습니다.

이 키는 문서 https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-SECRET_KEY 에 따라 비밀로 유지되어야합니다.

Django 프로젝트는 진행 중이며 일부 활성 사용자와 잠시 동안 실행되었습니다. 변경하면 어떤 효과가 SECRET_KEY있습니까? 기존 사용자, 쿠키, 세션 등이 영향을 받습니까? 분명히 새로운 것은 SECRET_KEY더 이상 공공 장소에 저장되지 않을 것입니다.

답변:


199

편집 :이 답변은 django 1.5를 기반으로합니다

SECRET_KEY 다양한 장소에서 사용됩니다. 먼저 영향을받는 대상을 지적한 다음 해당 목록을 살펴보고 그 영향에 대한 정확한 설명을 제공합니다.

SECRET_KEY직접 또는 간접적으로 사용하는 것의 목록 :

실제로 사용 여기에 나열된 항목의 많은 SECRET_KEY통해 django.utils.crypt.get_random_string()그것을 사용하는 랜덤 엔진을 종자합니다. 값이 변경 되더라도 영향을받지 않습니다 SECRET_KEY.

가치 변화에 직접적인 영향을받는 사용자 경험은 다음과 같습니다.

  • 세션에서 데이터 디코딩이 중단되어 모든 세션 백엔드 (쿠키, 데이터베이스, 파일 기반 또는 캐시)에 유효합니다.
  • 이미 전송 된 비밀번호 재설정 토큰이 작동하지 않습니다. 사용자는 새 토큰을 요청해야합니다.
  • 주석 양식 (을 사용하는 경우 django.contrib.comments)은 값이 변경되기 전에 요청되고 값이 변경된 후에 제출되었는지 여부를 검증하지 않습니다. 나는 이것이 매우 작지만 사용자에게는 혼란 스러울 수 있다고 생각합니다.
  • 에서 보낸 메시지 django.contrib.messages는 메모 양식과 동일한 타이밍 조건에서 서버 측의 유효성을 검사하지 않습니다.

업데이트 : 이제 django 1.9.5에서 작업 중이며 소스를 간략하게 살펴보면 거의 같은 대답을 얻을 수 있습니다. 나중에 철저한 검사를 수행 할 수 있습니다.


1
로컬 dev 서버에서 SECRET_KEY를 변경하고 있는데 로그 아웃하지 않으므로 변경 후 적어도 세션 (캐시)이 올바르게 작동하는 것 같습니다. 당신이 의미하는 바에 대해 더 자세히 설명 data decode will break하고 깨질 수있는 코드 (장고 또는 예제 프로젝트)를 지적 할 수 있습니까? 편집 : 여전히 django 1.4를 사용하는 경우입니까?
Kirill Zaitsev

@teferi 1.4에 대해 모르는 것은 코드를 살펴 보는 문제입니다. 각 포인트에 대한 모든 소스를 지적 했으므로 "세션 데이터 보호 및 임의 세션 키 생성"을 살펴볼 수 있습니다. 로그인 상태는 정상이지만 세션 데이터를 해시하는 데 사용 SECRET_KEY되는 세션에 포함 된 데이터를 읽을 수 없습니다 salted_hmac.
sberder

암호 해시 솔트에 사용되는 경우 데이터베이스의 암호를 재설정해야합니까?
Henning

7
@Henning 나는 그렇게 생각하지 않습니다. 암호가 저장됩니다 으로 <algorithm>$<iterations>$<salt>$<hash>임의의 소금이 각각의 경우에 암호와 함께 저장되어 있으므로, AUTH_USER있다.
Denis Drescher 2016 년

2
Django 버전> 1.5에서 답이 크게 다를까요? (예 : 현재 현재 1.9)
das-g

36

이 질문이 제기 된 이후, Django 설명서 가 답변을 포함하도록 변경되었습니다.

비밀 키는 다음 용도로 사용됩니다.

  • 모든 세션은 당신이 아닌 다른 세션 백엔드를 사용하는 경우 django.contrib.sessions.backends.cache, 또는 기본값을 사용하고 있습니다 get_session_auth_hash().
  • 모든 메시지는 당신이 사용하는 경우 CookieStorageFallbackStorage.
  • 모든 PasswordResetView토큰.
  • 다른 키가 제공되지 않는 한 암호화 서명 사용.

비밀 키를 돌리면 위의 모든 것이 무효화됩니다. 비밀 키는 사용자의 암호에 사용되지 않으며 키 회전은 영향을 미치지 않습니다.

비밀 키를 어떻게 회전시켜야하는지 정확히 알 수 없었습니다. Django가 새로운 프로젝트의 키를 생성하는 방법 과 다른 옵션 을 논의하는 요지에 대한 토론을 찾았습니다 . 마지막으로 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.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
$

4
비밀 키 생성은 비밀 키에 의존합니까?
kdazzle

4
아니요, @kdazzle,의 소스 코드를startproject 보면 crypto모듈을 사용하여 임의의 문자열을 생성한다는 것을 알 수 있습니다 .
돈 커크비

12
죄송합니다, @DonKirkby, 나쁜 농담
kdazzle

16

이 페이지 https://docs.djangoproject.com/en/dev/topics/signing/ 에 따르면 SECRET_KEY는 주로 일시적인 물건에 사용됩니다-예를 들어 변조를 감지 할 수 있도록 와이어를 통해 전송되는 데이터에 서명합니다. COULD가 깨지는 것은 다음과 같습니다.

  • 서명 된 쿠키 (예 : "이 컴퓨터의 내 인증 정보 기억") 유형 값 이 경우 쿠키가 무효화되고 서명이 확인되지 않고 사용자가 다시 인증해야합니다.
  • 비밀번호 재설정 또는 사용자 정의 파일 다운로드를위한 링크를 요청한 사용자의 경우 해당 링크는 더 이상 유효하지 않습니다. 사용자는 단순히 해당 링크를 다시 요청해야합니다.

나보다 최신 및 / 또는 현저한 장고 경험을 가진 사람이 다른 방법으로 차임 할 수도 있지만 서명 API로 명시 적으로 작업을 수행하지 않는 한 사용자에게 약간의 불편 함을 초래할 것으로 생각됩니다.


6
그렇다면 각 서버를 다시 시작할 때마다 새 키를 생성하지 않는 이유는 무엇입니까?
osa

4
여러 프로세스를 사용하여 동일한 서버를 실행하는 경우 문제가 발생할 수 있습니다.
dbn

1
@osa 코드를 푸시하거나 서버를 다시 시작할 때마다 모든 사용자를 로그 아웃 하시겠습니까?
EralpB

6

SECRET_KEY 문자열은 주로 쿠키 데이터를 암호화 및 / 또는 해싱하는 데 사용됩니다. 기본 세션 쿠키에는 자체 단점이 있기 때문에 많은 프레임 워크 (Django 포함)가 여기에옵니다.

숨겨진 필드로 기사를 편집하기 위해 django로 양식을 가지고 있다고 상상해보십시오. 이 숨겨진 필드에는 편집중인 기사의 ID가 저장됩니다. 아무도 다른 기사 ID를 보낼 수 없도록하려면 해시 ID가있는 숨겨진 필드를 추가합니다. 따라서 누군가가 ID를 변경하면 해시가 동일하지 않기 때문에 ID를 알 수 있습니다.

물론 이것은 간단한 예이지만 SECRET_KEY가 사용되는 방식입니다.

장고는 예를 들어 {% csrf_token %} 및 그 밖의 몇 가지를 위해 내부적으로 사용합니다. 질문에 따라 사용하지 않고 응용 프로그램을 변경하더라도 응용 프로그램에 영향을 미치지 않아야합니다.

유일한 것은이다 아마 세션 값이 삭제됩니다. 예를 들어 django는 다른 키로 세션을 디코딩 할 수 없으므로 사용자는 관리자로 다시 로그인해야합니다.


1

나는이 같은 실수를했다. 기본 암호는 50 자이므로 powershell을 사용하여 50 개의 긴 임의 문자열을 생성하고 이전 SECRET_KEY를 암호로 바꿨습니다. 로그인했고 SECRET_KEY를 교체 한 후 이전 세션이 무효화되었습니다.

Powershell 사용 ( 소스 ) :

# 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)

배쉬 ( 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의 긴 키로 시도했습니다. 둘 다 일했다. 소스 코드를 이해하면 서명자 함수가 반환하는 객체는 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 비트 ) 로 덮여 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.