Django 2.1 - Cryptographic signing

क्रिप्टोग्राफिक हस्ताक्षर




django

क्रिप्टोग्राफिक हस्ताक्षर

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

Django, मूल्यों पर हस्ताक्षर करने के लिए निम्न-स्तरीय एपीआई और हस्ताक्षरित कुकीज़ को स्थापित करने और पढ़ने के लिए एक उच्च-स्तरीय एपीआई दोनों प्रदान करता है, जो वेब अनुप्रयोगों में हस्ताक्षर करने के सबसे सामान्य उपयोगों में से एक है।

आपको निम्नलिखित के लिए उपयोगी हस्ताक्षर भी मिल सकते हैं:

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

SECRET_KEY सुरक्षा करना

जब आप startproject का उपयोग करके एक नया Django प्रोजेक्ट startproject , तो settings.py startproject फ़ाइल स्वचालित रूप से उत्पन्न होती है और एक यादृच्छिक SECRET_KEY मान प्राप्त करता है। यह मान हस्ताक्षरित डेटा हासिल करने की कुंजी है - यह महत्वपूर्ण है कि आप इसे सुरक्षित रखें, या हमलावर इसका उपयोग अपने स्वयं के हस्ताक्षरित मूल्य बनाने के लिए कर सकते हैं।

निम्न-स्तरीय API का उपयोग करना

Django के हस्ताक्षर करने के तरीके django.core.signing मॉड्यूल में रहते हैं। एक मूल्य पर हस्ताक्षर करने के लिए, पहले एक Signer उदाहरण को तत्काल करें:

>>> from django.core.signing import Signer
>>> signer = Signer()
>>> value = signer.sign('My string')
>>> value
'My string:GdMGD6HNQ_qdgxYP8yBZAdAIV1w'

बृहदान्त्र का अनुसरण करते हुए, हस्ताक्षर को स्ट्रिंग के अंत में जोड़ा जाता है। आप unsign विधि का उपयोग करके मूल मान प्राप्त कर सकते हैं:

>>> original = signer.unsign(value)
>>> original
'My string'

यदि हस्ताक्षर या मूल्य को किसी भी तरह से बदल दिया गया है, तो django.core.signing.BadSignature अपवाद उठाया जाएगा:

>>> from django.core import signing
>>> value += 'm'
>>> try:
...    original = signer.unsign(value)
... except signing.BadSignature:
...    print("Tampering detected!")

डिफ़ॉल्ट रूप से, Signer वर्ग Signer लिए SECRET_KEY सेटिंग का उपयोग करता है। आप इसे Signer कंस्ट्रक्टर को पास करके एक अलग सीक्रेट का उपयोग कर सकते हैं:

>>> signer = Signer('my-other-secret')
>>> value = signer.sign('My string')
>>> value
'My string:EkfQJafvGyiofrdGnuthdxImIJw'
class Signer(key=None, sep=':', salt=None) [source]

एक हस्ताक्षरकर्ता को लौटाता है जो हस्ताक्षर बनाने और अलग-अलग मानों के लिए sep का उपयोग करता है। sep URL सुरक्षित base64 वर्णमाला में नहीं हो सकता है। इस वर्णमाला में अल्फ़ान्यूमेरिक वर्ण, हाइफ़न और अंडरस्कोर हैं।

salt तर्क का उपयोग करना

यदि आप किसी विशेष स्ट्रिंग की प्रत्येक घटना के लिए एक ही हस्ताक्षर हैश करने की इच्छा नहीं रखते हैं, तो आप Signer इन वर्ग के लिए वैकल्पिक salt तर्क का उपयोग कर सकते हैं। नमक का उपयोग करने से नमक और आपके SECRET_KEY दोनों के साथ हस्ताक्षरित हैश फ़ंक्शन का बीज होगा:

>>> signer = Signer()
>>> signer.sign('My string')
'My string:GdMGD6HNQ_qdgxYP8yBZAdAIV1w'
>>> signer = Signer(salt='extra')
>>> signer.sign('My string')
'My string:Ee7vGi-ING6n02gkcJ-QLHg6vFw'
>>> signer.unsign('My string:Ee7vGi-ING6n02gkcJ-QLHg6vFw')
'My string'

इस तरह से नमक का उपयोग विभिन्न हस्ताक्षरों को अलग-अलग नामस्थानों में रखता है। एक हस्ताक्षर जो एक नाम स्थान (एक विशेष नमक मान) से आता है, एक समान प्लेनटेक्स्ट स्ट्रिंग को एक अलग नामस्थान में मान्य करने के लिए उपयोग नहीं किया जा सकता है जो एक अलग नमक सेटिंग का उपयोग कर रहा है। परिणाम एक हमलावर को कोड में एक जगह पर हस्ताक्षर किए गए स्ट्रिंग का उपयोग करने से रोकने के लिए होता है जो कोड के एक अन्य टुकड़े के इनपुट के रूप में होता है और एक अलग नमक का उपयोग करके हस्ताक्षर (और सत्यापन) उत्पन्न कर रहा है।

SECRET_KEY विपरीत, आपके नमक तर्क को गुप्त रहने की आवश्यकता नहीं है।

टाइमस्टैम्पड मूल्यों का सत्यापन

TimestampSigner Signer का एक उपवर्ग है जो एक हस्ताक्षरित टाइमस्टैम्प को मूल्य पर जोड़ता है। यह आपको यह पुष्टि करने की अनुमति देता है कि एक हस्ताक्षरित मूल्य समय की एक निर्दिष्ट अवधि के भीतर बनाया गया था:

>>> from datetime import timedelta
>>> from django.core.signing import TimestampSigner
>>> signer = TimestampSigner()
>>> value = signer.sign('hello')
>>> value
'hello:1NMg5H:oPVuCqlJWmChm1rA2lyTUtelC-c'
>>> signer.unsign(value)
'hello'
>>> signer.unsign(value, max_age=10)
...
SignatureExpired: Signature age 15.5289158821 > 10 seconds
>>> signer.unsign(value, max_age=20)
'hello'
>>> signer.unsign(value, max_age=timedelta(seconds=20))
'hello'
class TimestampSigner(key=None, sep=':', salt=None) [source]
sign(value) [source]

value हस्ताक्षर करें और इसमें वर्तमान टाइमस्टैम्प को जोड़ें।

unsign(value, max_age=None) [source]

जाँचता है कि क्या value को max_age सेकंड से कम समय पहले SignatureExpired किया गया था, अन्यथा SignatureExpired उठाता है। max_age पैरामीटर एक पूर्णांक या एक datetime.timedelta ऑब्जेक्ट को स्वीकार कर सकता है।

जटिल डेटा संरचनाओं की सुरक्षा करना

यदि आप एक सूची, टपल या शब्दकोश की रक्षा करना चाहते हैं, तो आप साइनिंग मॉड्यूल के dumps और loads कार्यों का उपयोग करके ऐसा कर सकते हैं। ये पायथन के अचार मॉड्यूल का अनुकरण करते हैं, लेकिन हुड के नीचे JSON क्रमांकन का उपयोग करते हैं। JSON यह सुनिश्चित करता है कि भले ही आपका SECRET_KEY चोरी हो गया हो, हमलावर अचार प्रारूप का फायदा उठाकर मनमाने आदेशों को निष्पादित करने में सक्षम नहीं होगा:

>>> from django.core import signing
>>> value = signing.dumps({"foo": "bar"})
>>> value
'eyJmb28iOiJiYXIifQ:1NMg1b:zGcDE4-TCkaeGzLeW9UQwZesciI'
>>> signing.loads(value)
{'foo': 'bar'}

JSON की प्रकृति के कारण (सूचियों और टुपल्स के बीच कोई मूल अंतर नहीं है) यदि आप एक ट्यूपल में गुजरते हैं, तो आपको signing.loads(object) से एक सूची मिलेगी। signing.loads(object) :

>>> from django.core import signing
>>> value = signing.dumps(('a','b','c'))
>>> signing.loads(value)
['a', 'b', 'c']
dumps(obj, key=None, salt='django.core.signing', compress=False) [source]

URL-safe, sha1 हस्ताक्षरित base64 संकुचित JSON स्ट्रिंग देता है। TimestampSigner का उपयोग करके सीरियल ऑब्जेक्ट पर हस्ताक्षर किए गए हैं।

loads(string, key=None, salt='django.core.signing', max_age=None) [source]

dumps() का उल्टा, BadSignature उठाता है अगर हस्ताक्षर विफल होता है। अगर दिया जाता है (सेकंड में) max_age