Django के SECRET_KEY को बदलने के प्रभाव


202

मैंने एक गलती की और अपने Django प्रोजेक्ट 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
मैं अपने स्थानीय देव सर्वर पर SECRET_KEY बदल रहा हूं और यह मुझे लॉग आउट नहीं करता है, इसलिए ऐसा लगता है कि परिवर्तन के बाद कम से कम सत्र (कैश) सही ढंग से काम करते हैं। क्या आप इसके बारे में विस्तार से बता सकते हैं कि आपका क्या मतलब है data decode will breakऔर हो सकता है कि कुछ कोड (django या उदाहरण परियोजना में) इंगित करें जो टूट जाएगा? संपादित करें: अभी भी django 1.4 का उपयोग कर रहा है - क्या यह मामला है?
किरिल जैतसेव

@teferi मुझे 1.4 के बारे में नहीं पता है, यह कोड पर एक नज़र रखने की बात है। मैंने प्रत्येक बिंदु के लिए सभी स्रोतों पर ध्यान दिया, आप "सत्र डेटा की सुरक्षा और यादृच्छिक सत्र कुंजियाँ बनाने" पर एक नज़र डाल सकते हैं। यह सामान्य है कि आप अभी भी लॉग इन हैं लेकिन आप सत्र में निहित डेटा को नहीं पढ़ पाएंगे क्योंकि SECRET_KEYइसका उपयोग salted_hmacसत्र डेटा को हैश करने के लिए किया जाता है।
sderder

अगर इसका उपयोग पासवर्ड हैश नमक के लिए किया जाता है, तो क्या इसका मतलब डेटाबेस में पासवर्ड रीसेट नहीं होना है?
हेनिंग

7
@ मुझे ऐसा नहीं लगता। पासवर्ड जमा हो जाती है के रूप में <algorithm>$<iterations>$<salt>$<hash>, auth_user में इतना यादृच्छिक नमक प्रत्येक मामले में पासवर्ड के साथ संग्रहीत किया जाता है।
डेनिस ड्रैशर

2
क्या Django संस्करण> 1.5 के लिए उत्तर काफी अलग होगा? (जैसे अब-वर्तमान 1.9)
दास-जी

36

चूंकि यह सवाल पूछा गया था, इसलिए Django प्रलेखन में एक उत्तर शामिल है।

गुप्त कुंजी का उपयोग इसके लिए किया जाता है:

  • यदि आप किसी अन्य सत्र बैकएंड django.contrib.sessions.backends.cacheका उपयोग कर रहे हैं या डिफ़ॉल्ट का उपयोग कर रहे हैं तो सभी सत्र get_session_auth_hash()
  • सभी संदेश यदि आप उपयोग कर रहे हैं CookieStorageया FallbackStorage
  • सभी 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

अपडेट करें

ऐसा लगता है कि Django ने get_random_secret_key()फ़ंक्शन को संस्करण 1.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
$

4
क्या गुप्त कुंजी पीढ़ी गुप्त कुंजी पर निर्भर करती है?
kdazzle

4
नहीं, @kdazzle, यदि आप के लिए स्रोत कोडstartproject को देखते हैं, तो आप देख सकते हैं कि यह सिर्फ cryptoमॉड्यूल का उपयोग करके एक यादृच्छिक स्ट्रिंग उत्पन्न करता है ।
डॉन किर्कबी

12
हेह, क्षमा करें, @ डॉर्ककिर्बी, बुरा मजाक
kdazzle

16

इस पृष्ठ के अनुसार https://docs.djangoproject.com/en/dev/topics/signing/ , SECRET_KEY का उपयोग ज्यादातर क्षणभंगुर सामान के लिए किया जाता है - तार पर भेजे गए डेटा पर हस्ताक्षर करना ताकि आप छेड़छाड़ का पता लगा सकें, उदाहरण के लिए। यह उन चीजों की तरह दिखता है जो COULD ब्रेक हैं:

  • हस्ताक्षरित कुकीज़, उदाहरण के लिए "इस कंप्यूटर पर मेरी स्थिति याद रखें" प्रकार मान। इस स्थिति में, कुकी अमान्य हो जाएगी, हस्ताक्षर सत्यापित करने में विफल हो जाएगा और उपयोगकर्ता को फिर से प्रमाणित करना होगा।
  • जिन उपयोगकर्ताओं ने पासवर्ड रीसेट या कस्टम फ़ाइल डाउनलोड के लिए लिंक का अनुरोध किया है, वे लिंक अब मान्य नहीं होंगे। उपयोगकर्ताओं को बस उन लिंक को फिर से अनुरोध करना होगा।

मुझसे अधिक हाल ही में और / या मेरे साथ सलामी Django के अनुभव के साथ कोई अन्यथा झंकार कर सकता है, लेकिन मुझे संदेह है कि जब तक आप स्पष्ट रूप से हस्ताक्षर करने वाले एपीआई के साथ कुछ नहीं कर रहे हैं, यह केवल आपके उपयोगकर्ताओं के लिए एक हल्की असुविधा पैदा करना चाहिए।


6
फिर प्रत्येक सर्वर पुनरारंभ पर एक नई कुंजी क्यों नहीं उत्पन्न होती है?
osa

4
यदि आप एक ही सर्वर को कई प्रक्रियाओं का उपयोग करके चला रहे हैं, तो यह संभवतः एक समस्या का कारण होगा।
dbn

1
क्या आप कोड को पुश करने / अपना सर्वर पुनरारंभ करने के लिए हर बार अपने सभी उपयोगकर्ताओं को लॉग इन करना चाहेंगे?
एरलप बी

6

SECRET_KEY स्ट्रिंग को मुख्य रूप से एन्क्रिप्ट और / या हैशिंग कुकीज़ डेटा के लिए उपयोग किया जाता है। बहुत सारे चौखटे (Django सहित) डिफ़ॉल्ट सत्र कुकीज़ के पास अपनी कमियां होने के कारण आते हैं।

कल्पना कीजिए कि आपके पास एक छिपे हुए क्षेत्र के साथ लेख संपादित करने के लिए django में है। इस छिपे हुए क्षेत्र में आपके द्वारा संपादित लेख की आईडी संग्रहीत है। और अगर आप यह सुनिश्चित करना चाहते हैं कि कोई भी आपको कोई अन्य लेख आईडी नहीं भेज सकता है, तो आप हैशेड आईडी के साथ एक अतिरिक्त छिपा क्षेत्र जोड़ देंगे। इसलिए अगर कोई व्यक्ति आईडी बदल देगा, तो आपको पता चल जाएगा क्योंकि हैश समान नहीं होगा।

बेशक यह एक तुच्छ उदाहरण है लेकिन यह है कि SECRET_KEY का उपयोग कैसे किया जाता है।

Django आंतरिक रूप से {% csrf_token%} और कुछ और चीजों के लिए उपयोग कर रहा है। यदि आपके प्रश्न का उपयोग नहीं कर रहे हैं और आप इसका उपयोग नहीं कर रहे हैं, तो इसका आपके आवेदन पर वास्तव में कोई प्रभाव नहीं होना चाहिए।

बात सिर्फ इतनी है कि हो सकता है सत्र मूल्यों को गिरा दिया जाएगा। इसलिए उदाहरण के लिए उपयोगकर्ताओं को फिर से व्यवस्थापक में प्रवेश करना होगा, क्योंकि django अलग-अलग कुंजी के साथ सत्र को डिकोड करने में सक्षम नहीं होगा।


1

मैंने यही गलती की। डिफ़ॉल्ट पासवर्ड 50 लंबा था इसलिए मैंने 50 लंबी यादृच्छिक स्ट्रिंग उत्पन्न करने के लिए पॉवरशेल का उपयोग किया और पुराने SECRET_KEY को इसके साथ बदल दिया। मुझे लॉग इन किया गया था और SECRET_KEY के स्थान पर मेरे पिछले सत्र को अमान्य कर दिया गया था।

पॉवर्सशेल ( स्रोत ) के साथ:

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

बाश ( स्रोत ) के साथ:

# 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 लंबी कुंजी के साथ आज़माया। दोनों ने काम किया। यदि मैं स्रोत कोड को समझता हूं , तो हस्ताक्षरकर्ता फ़ंक्शन द्वारा लौटाए गए ऑब्जेक्ट बेस 64 में एक एचएमएसी हैश है। RFC 2104 के पास HMAC गुप्त कुंजी की आवश्यक लंबाई के लिए कहने के लिए यह है।

बी बाइट्स की तुलना में अधिक समय तक कुंजियों का उपयोग करने वाले एप्लिकेशन पहले एच का उपयोग करके कुंजी को हैश करेंगे और फिर एचएमएसी को वास्तविक कुंजी के रूप में परिणामी एल बाइट स्ट्रिंग का उपयोग करेंगे।

HMAC की कुंजी किसी भी लम्बाई की हो सकती है (B बाइट्स की तुलना में अधिक समय पहले H का उपयोग करके हैशेड किया जाता है)। हालांकि, एल बाइट्स से कम दृढ़ता से हतोत्साहित किया जाता है क्योंकि यह फ़ंक्शन की सुरक्षा ताकत को कम करेगा। एल बाइट्स की तुलना में लंबे समय तक कुंजी स्वीकार्य हैं, लेकिन अतिरिक्त लंबाई फ़ंक्शन शक्ति में उल्लेखनीय रूप से वृद्धि नहीं करेगी। (यदि कुंजी की यादृच्छिकता को कमजोर माना जाता है तो एक लंबी कुंजी उचित हो सकती है।)

सामान्य बोल में अनुवाद करने के लिए, गुप्त कुंजी का आकार आउटपुट के समान आकार होना चाहिए। चाबी भी बिट्स में होना चाहिए। बेस 64 में प्रत्येक अंक 6 बिट्स का प्रतिनिधित्व करता है। इसलिए यदि आपके पास 50 वर्ण का पासवर्ड है, तो आपके पास 50 x 6 = 300 बिट गुप्त कुंजी होगी। यदि आप SHA256 का उपयोग कर रहे हैं, तो आपको 256 बिट कुंजी की आवश्यकता होगी ( sha256 परिभाषा द्वारा 256 बिट्स का उपयोग करता है )। तो जब तक आप SHA256 से बड़े हैशिंग एल्गोरिथ्म का उपयोग करने की योजना नहीं बनाते हैं, तब तक 50 लंबा पासवर्ड काम करना चाहिए।

लेकिन जब से कुंजी में कोई अतिरिक्त बिट्स हैशेड किया जा रहा है, तो इसके आकार में प्रदर्शन में भारी कमी नहीं होगी। लेकिन यह आपको गारंटी देगा कि आपके पास बड़े हैश कार्यों के लिए पर्याप्त बिट्स हैं। SHA-512 एक 100 लंबे SECRET_KEY ( 50 x 6 = 600 बिट> 512 बिट्स ) द्वारा कवर किया जाएगा ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.