2013-05-02 14 views
6

मेरे देश की सरकार ने ईरान के बाहर सुरक्षित वेब सेवाओं तक पहुंच को अवरुद्ध करने के लिए HTTPS गति को प्रतिबंधित कर दिया है। अब मेरे ग्राहक अपने खातों में लॉग इन करने के लिए दर्द में हैं। मुझे पता है कि वर्तमान खाता पासवर्ड pbkdf2_sha256 एल्गोरिदम का उपयोग करके एन्क्रिप्टेड और नमकीन हैं और sha256 हैश को पचाने के लिए कुछ जावास्क्रिप्ट/jQuery libs हैं।सादे पाठ पासवर्ड के बजाय sha256 हैश का उपयोग करें

मेरा प्रश्न: क्या कोई दर्द रहित तरीका है (जिसे मूल django.contrib.auth को पुनः लिखने/बदलने की आवश्यकता नहीं है) AJAX अनुरोधों द्वारा लॉगिन पासवर्ड के रूप में भेजा गया sha256 हैश का उपयोग करने के लिए?

अद्यतन: मैं ईरान के अंदर अपनी साइटों को होस्ट करने की योजना बना रहा हूं (जो 5 गुना अधिक महंगा और निश्चित रूप से सरकार द्वारा नियंत्रित है) लेकिन कम से कम HTTPS प्रोटोकॉल प्रतिबंधित नहीं है। HTTP चैनल के माध्यम से या तो सादा पाठ या पचाने वाले तरीके में पासवर्ड भेजना असुरक्षित है। एक वेब डेवलपर (और नेटवर्क विशेषज्ञ नहीं) के रूप में मुझे लगता है कि वे किसी भी समय हैश/सत्र आईडी/कुकीज़ को इकट्ठा/स्नीफ कर सकते हैं, समस्या को हल करने के लिए परिष्कृत ज्ञान और प्रयासों की आवश्यकता होती है और मेरी सभी साइट को सुरक्षा के स्तर की आवश्यकता नहीं होती है । हम विभिन्न ग्रहों में रहते हैं।

+1

स्टैक ओवरफ़्लो में आपका स्वागत है। कृपया [अधिक विनम्र भाषा का उपयोग करने का प्रयास करें] (http://meta.stackexchange.com/questions/22232/are-expletives-allowed-on-se-sites/22233#22233)। – nnnnnn

+3

धन्यवाद। शब्दों के लिए खेद है। मैं पिछले 33 घंटों से सो नहीं रहा हूं और अपने सिर को दीवार पर मार रहा हूं जो मेरी गलती के कारण नहीं है। – GhaghaSibil

उत्तर

3

आप कच्चे पासवर्ड का उपयोग करने के लिए अपने स्वयं के प्रमाणीकरण बैकएंड लिख सकते हैं:

from django.contrib.auth import backends 
from django.contrib.auth.models import User 

class RawPasswordUser(User): 
    class Meta: 
     proxy = True 

    def set_password(self, raw_password): 
     # default implementation made a hash from raw_password, 
     # we don't want this 
     self.password = raw_password 

    def check_password(self, raw_password): 
     # same here, don't make hash out of raw_password 
     return self.password == raw_password 

class ModelBackend(backends.ModelBackend): 
    def authenticate(self, username=None, password=None): 
     try: 
      user = RawPasswordUser.objects.get(username=username) 
      if user.check_password(password): 
       return user 
     except RawPasswordUser.DoesNotExist: 
      return None 

    def get_user(self, user_id): 
     try: 
      return RawPasswordUser.objects.get(pk=user_id) 
     except RawPasswordUser.DoesNotExist: 
      return None 

सेटिंग्स फ़ाइल में:

AUTHENTICATION_BACKENDS = (
    # ModelBackend from project_root/auth/backends.py 
    'auth.backends.ModelBackend', 
) 

अब जब आप authenticate अपने विचारों में उपयोगकर्ताओं, आप RawPasswordUser उदाहरणों मिल जाएगा। यह login_required सजावट पर लागू होता है, request.user प्रॉक्सी क्लास को इंगित करेगा।

विवरण के लिए documentation देखें।

डिफ़ॉल्ट उपयोगकर्ता के साथ डिफ़ॉल्ट उपयोगकर्ता मॉडल को प्रतिस्थापित करने के लिए Django 1.5+ there is also an option के लिए, लेकिन मौजूदा उपयोगकर्ताओं को रखने के लिए आपको उन्हें किसी भी तरह माइग्रेट करना होगा, this question देखें।


दरअसल आप उपयोगकर्ता पासवर्ड अपरिवर्तित रखने में सक्षम नहीं होंगे।

करके निम्न स्वरूप में डिफ़ॉल्ट Django पासवर्ड संगृहीत:

एल्गोरिथ्म $ पुनरावृत्तियों $ नमक $ हैश

जिसका मतलब है:

  • तुम बस पासवर्ड को पुनर्जीवित नहीं कर सकता मूल के हैंश से, क्योंकि आपके पास मूल नहीं है।

  • आप नमक को जानने के बिना क्लाइंट-साइड पर एक ही हैश उत्पन्न करने में सक्षम नहीं होंगे। आप इसे क्लाइंट-साइड में पास कर सकते हैं, लेकिन नमक को एक रहस्य माना जाता है, इसलिए इसे अनएन्क्रिप्टेड चैनल के माध्यम से करना मूर्ख नहीं है।

सबसे आसान समाधान है कि मैं देख रहा हूँ, वर्तमान Django व्यवहार रखने के लिए के रूप में टिप्पणी में Tadeck द्वारा सुझाव दिया गया था, क्लाइंट-साइड और बल उपयोगकर्ताओं के लिए hashing अपने पासवर्ड बदल लें जोड़ने है।

ठीक है, यह वास्तव में एक समाधान नहीं है, क्योंकि एक हमलावर पचाने वाले पासवर्ड को रोक सकता है और सीधे उनका उपयोग कर सकता है, लेकिन आपने इसे अपने प्रश्न अद्यतन का उल्लेख किया है। चूंकि आपको अधिक सुरक्षा की परवाह नहीं है, इसलिए आप जावास्क्रिप्ट में public key encryption चेकआउट भी कर सकते हैं।


एक अन्य समाधान Tadeck द्वारा प्रस्तावित OAuth की तरह सेवा, इस तरह कुछ हद तक लग सकता है जो उपयोग करने के लिए है:

def index(request): 
    access_token = request.REQUEST.get('token', None) 
    if not access_token: 
     return redirect('login') 

    # Custom authentication backend that accepts a token 
    # and searches for a user with that token in database. 
    user = authenticate(access_token) 
    if not user: 
     return redirect('login') 

    return render(...) 

def auth(request): 
    ''' This ajax-view has to be encrypted with SSL.''' 
    # Normal Django authentication. 
    user = authenticate(request.POST['username'], request.POST['password']) 

    # Authentication failed 
    if user is None: 
     return json.dumps({'error': '...'}) 

    # generate, save and return token in json response 
    token = UserToken(user=user, value=generate_token()) 
    # token.expires_at = datetime.now() + timedelta(days=1) 
    token.save() 

    return json.dumps({'token': token.value}) 

एक हमला अभी भी पहुंच टोकन को रोक सकता है, लेकिन यह एक बिट में अवरोध डालने की तुलना में बेहतर है पासवर्ड हैश

+0

मैं 'user = user.objects.get (...)' –

+0

के नीचे 'छोड़कर' नीचे रखूंगा क्या इसे वर्तमान बैकएंड रिकॉर्ड बदलना आवश्यक है? मेरा मतलब है कि इस नए बैकएंड का उपयोग करते समय वर्तमान उपयोगकर्ताओं को अपना पासवर्ड बदलना चाहिए? क्या मैं उन्हें बदलने के लिए कुछ स्क्रिप्ट लिख सकता हूं? – GhaghaSibil

+0

पासवर्ड एक हैश बने रहेंगे, आप अपने क्लाइंट-साइड एक ही हैंश भेजता है, तो आपको कुछ भी बदलने की आवश्यकता नहीं है। यदि हैश अलग हैं, तो आप 'python manage.py shell' में परिवर्तित कर सकते हैं, आयात करें' django.contrib.auth.models.User' और अपनी इच्छानुसार संशोधित करें। – gatto

संबंधित मुद्दे