JWT पर हस्ताक्षर करना और उन्हें सत्यापित करना
JWT तीन base64url खंड हैं — हेडर, पेलोड, हस्ताक्षर — और पहले दो टोकन रखने वाले किसी भी व्यक्ति के लिए पठनीय हैं। एक को डिकोड करना बताता है कि वह क्या दावा करता है; केवल तीसरा खंड बताता है कि उस पर विश्वास करें या नहीं। यह लेख उसी तीसरे खंड के बारे में है: हस्ताक्षर कैसे बनता है, कौन उसे बना सकता है, सत्यापनकर्ता उसे कैसे जाँचते हैं, और वह सटीक बिंदु जहाँ "सत्यापित" का अर्थ "भरोसेमंद" होना बंद हो जाता है। आप हर कदम स्वयं JWT हस्ताक्षरकर्ता और सत्यापनकर्ता में चला सकते हैं, जो आपके ब्राउज़र में स्थानीय रूप से हस्ताक्षर करता और सत्यापित करता है।
डिकोड करना सत्यापित करना नहीं है
JWT के बारे में सबसे आम गलतफ़हमी सबसे खतरनाक भी है: कि टोकन पढ़ना उसे जाँचने के समान है। ऐसा नहीं है। हेडर और पेलोड base64url हैं — एक एन्कोडिंग, एन्क्रिप्शन नहीं — इसलिए जो कोई टोकन रोक ले, उसे किसी लॉग में पा ले, या ब्राउज़र की local storage से उसकी प्रतिलिपि बना ले, वह बिना किसी कुंजी के सेकंडों में उसे डिकोड कर सकता है। अंदर के दावे (यह किसके लिए है, कब समाप्त होता है, कौन-सी भूमिकाएँ दावा करता है) दावे हैं, और दावे सस्ते होते हैं।
हस्ताक्षर इसीलिए मौजूद है क्योंकि दावे सस्ते हैं। यह हेडर, पेलोड और एक ऐसी कुंजी के बीच क्रिप्टोग्राफ़िक बंधन है जो केवल जारीकर्ता के पास है: पेलोड का एक अक्षर बदलें और हस्ताक्षर मेल खाना बंद कर देता है। सत्यापन उसी गणित को दोहराने का कार्य है — प्राप्त हेडर और पेलोड पर जारीकर्ता की कुंजी से हस्ताक्षर फिर से गणना करना, और तुलना करना। यदि मेल खाता है, तो टोकन ठीक वैसा ही है जैसा जारीकर्ता ने हस्ताक्षरित किया था; यदि नहीं, तो कुछ बदल गया है, और उसके दावे कितने भी विश्वसनीय लगें, टोकन बेकार है।
सममित बनाम असममित: टोकन कौन बना सकता है
HS256 में जो रहस्य हस्ताक्षर करता है वही सत्यापित करता है। इससे HMAC तेज़, सरल और एक ही सेवा के भीतर पूरी तरह पर्याप्त बनता है — आपका API अपने टोकन स्वयं हस्ताक्षरित करता है और स्वयं जाँचता है, और रहस्य कभी भवन नहीं छोड़ता। जिस क्षण किसी दूसरे पक्ष को सत्यापित करना होता है, मॉडल टूट जाता है: उसे रहस्य देना उसे टोकन बनाने की शक्ति देना है, क्योंकि सत्यापन और हस्ताक्षर एक ही क्रिया हैं। लीक हुआ HMAC रहस्य सत्यापन की समस्या नहीं है; यह जालसाज़ी की समस्या है।
असममित एल्गोरिदम दोनों शक्तियों को अलग करते हैं। RS256, ES256 और EdDSA निजी कुंजी से हस्ताक्षर करते हैं और सार्वजनिक कुंजी से सत्यापित करते हैं, इसलिए जारीकर्ता अपनी सार्वजनिक कुंजियाँ — JWKS के रूप में — प्रकाशित कर सकता है, और दुनिया का हर सत्यापनकर्ता बिना जालसाज़ी की शक्ति रखे टोकन जाँच सकता है। यही बँटवारा JWT को सेवाओं के पार काम करने लायक बनाता है: आपका API किसी पहचान प्रदाता के टोकनों पर भरोसा करता है क्योंकि वह उस प्रदाता की प्रकाशित कुंजियों पर भरोसा करता है, इसलिए नहीं कि वह उसके साथ कोई रहस्य साझा करता है। इसकी कीमत जटिलता है — कुंजी प्रारूप, घुमाव, kid मिलान — जिसे इस साइट का हस्ताक्षरकर्ता और सत्यापनकर्ता ठोस बनाने के लिए मौजूद है।
एल्गोरिदम-कन्फ़्यूज़न हमला
क्लासिक JWT हमले को टूटी क्रिप्टोग्राफी की ज़रूरत नहीं है — उसे ऐसे सत्यापनकर्ता की ज़रूरत है जो टोकन पर भरोसा करके उसे अपना एल्गोरिदम बताने दे। हमलावर वैध RS256 टोकन लेता है, जिसकी सार्वजनिक कुंजी प्रकाशित है (जैसी सार्वजनिक कुंजियाँ होती हैं), और उसी पेलोड पर HS256 से फिर से हस्ताक्षर करता है, सार्वजनिक कुंजी को ही HMAC रहस्य के रूप में उपयोग करके। जो सत्यापनकर्ता हेडर से alg पढ़ता है और उसके अनुसार अपनी सत्यापन विधि चुनता है, वह अब सार्वजनिक कुंजी को रहस्य मानकर HMAC से जाली टोकन को "सत्यापित" कर देगा — और सार्वजनिक कुंजी सार्वजनिक है।
बचाव संरचनात्मक है, सलाह नहीं: सत्यापनकर्ता को स्वीकार्य एल्गोरिदम तय करने चाहिए, और कुंजी का परिवार एल्गोरिदम के परिवार से मेल खाना चाहिए — RSA कुंजी कभी HMAC टोकन सत्यापित नहीं कर सकती, और रहस्य कभी RSA टोकन सत्यापित नहीं कर सकता। जो सत्यापनकर्ता कुंजी को परिवारों के पार फिर से समझता है वह डिज़ाइन से ही टूटा हुआ है, चाहे उसकी क्रिप्टोग्राफी कितनी भी सही हो। इसीलिए इस साइट का सत्यापनकर्ता परिवार-पार कुंजियों को स्पष्ट चेतावनी के साथ मना करता है बजाय जाँच का प्रयास करने के: मना करना ही विशेषता है।
व्यवहार में JWKS और kid घुमाव कैसे दिखते हैं
पहचान प्रदाता एक शाश्वत कुंजी नहीं देता; वह एक सेट प्रकाशित करता है — JWKS, आमतौर पर /.well-known/jwks.json पर — और नई कुंजी जोड़कर तथा कुछ समय बाद पुरानी हटाकर कुंजियाँ घुमाता है। हर टोकन का हेडर एक kid रखता है जो हस्ताक्षर करने वाली कुंजी का नाम बताता है, इसलिए सत्यापनकर्ता सेट फ़ेच करता है, मेल खाती कुंजी चुनता है, और सत्यापित करता है। पुरानी कुंजी से हस्ताक्षरित टोकन तब तक काम करते रहते हैं जब तक वह हटाई नहीं जाती, और यही घुमाव को फ़्लैग डे के बजाय सुरक्षित बनाता है।
परिचालन विवरण वहीं टूटते हैं। सत्यापनकर्ताओं को JWKS कैश करनी चाहिए (हर अनुरोध पर उसे फ़ेच करना स्वयं-प्रेरित आउटेज है), उस स्थिति को संभालना चाहिए जहाँ kid अज्ञात हो — आमतौर पर घुमाव जिसे कैश ने अभी नहीं देखा है, इसलिए विफल होने से पहले फिर से फ़ेच करें — और अविश्वसनीय URL से कुंजी सेट कभी स्वीकार नहीं करनी चाहिए: सेट उतना ही भरोसेमंद है जितना वह चैनल जिससे वह आया, इसीलिए JWKS एंडपॉइंट HTTPS के पीछे रहते हैं और इसीलिए यहाँ का JWKS बिल्डर हर kid को कुंजी के ही RFC 7638 थंबप्रिंट से निकालता है, ताकि id को कुंजी से स्वतंत्र रूप से जाली न बनाया जा सके।
exp, nbf, iat — और घड़ी की समस्या
हस्ताक्षर साबित करता है कि टोकन हस्ताक्षरित था; यह कुछ नहीं कहता कि उसे अब भी माना जाना चाहिए या नहीं। वह समय दावों का काम है: exp (कब वह मान्य होना बंद करता है), nbf (कब वह शुरू होता है), iat (कब वह जारी किया गया था)। जो सत्यापनकर्ता हस्ताक्षर जाँचता है और घड़ी छोड़ देता है, वह टोकन को हमेशा के लिए स्वीकार करता है — एक साल पहले चुराया गया टोकन भी। छोटी अवधि व्यावहारिक उत्तर है: मिनटों में मापे जाने वाले एक्सेस टोकन, दीर्घकालिक भरोसा ले जाने वाले रीफ़्रेश टोकन, और रद्दीकरण केवल फिर से जारी न करके सुलझाया जाता है।
घड़ियाँ असहमत होती हैं, इसलिए सत्यापनकर्ता थोड़ी छूट देते हैं — आमतौर पर exp और nbf पर एक-दो मिनट की छूट — पर छूट विचलन की सहनशीलता है, समाप्ति को अनदेखा करने का लाइसेंस नहीं। जिस डिवाइस की घड़ी मिनटों से बाहर है, वह ऐसे टोकन बनाएगा जिन्हें उसका अपना सर्वर अस्वीकार कर देता है, और भविष्य के iat वाला टोकन जालसाज़ी का संकेत है, गोल करने की त्रुटि नहीं। वही घड़ी अनुशासन टूलींग पर भी लागू होता है: सत्यापनकर्ता समाप्ति को उसी घड़ी से जाँचता है जिसे आप देख सकते हैं, और टोकन के समाप्त होने पर यह बात साफ़ कहता है बजाय केवल "अमान्य" कहने के।
"सत्यापित" क्या साबित करता है और क्या नहीं
सत्यापित टोकन तीन बातें साबित करता है और बस इतना ही: हेडर और पेलोड ठीक वैसे ही हैं जैसे हस्ताक्षरित किए गए थे, हस्ताक्षरकर्ता के पास कुंजी थी, और टोकन अपनी वैधता अवधि के भीतर है। यह साबित नहीं करता कि जारीकर्ता वही है जो आप सोचते हैं — वह इस पर निर्भर है कि कुंजी कहाँ से आई, और हमलावर-नियंत्रित URL से फ़ेच की गई कुंजी हमलावर के टोकनों को पूरी तरह सत्यापित करती है। यह साबित नहीं करता कि दावे सच हैं — हस्ताक्षर कथन को प्रमाणित करता है, उसके पीछे के तथ्यों को नहीं। और यह साबित नहीं करता कि टोकन चुराया नहीं गया था: किसी के भी द्वारा प्रस्तुत वैध टोकन स्वीकार किया जाता है, इसीलिए टोकन अल्पकालिक और सीमित दायरे वाले होते हैं।
इसलिए भरोसे का निर्णय टोकन के बाहर रहता है। आपका API किसी टोकन पर भरोसा करता है क्योंकि उसने कुंजी अपने पहचान प्रदाता की well-known URL से HTTPS पर फ़ेच की, क्योंकि iss उस प्रदाता से मेल खाता है जिसे उसने कॉन्फ़िगर किया है, और क्योंकि aud उस सेवा से मेल खाता है जो वह है। सत्यापन अंतिम जाँच है, पहली नहीं: कुंजी की उत्पत्ति, जारीकर्ता, ऑडियंस, फिर हस्ताक्षर, फिर समय। जो टूल उस संदर्भ के बिना "VALID" बताता है वह गणित के बारे में सच कह रहा है और भरोसे के बारे में कुछ नहीं — इसीलिए इस साइट का सत्यापनकर्ता यह बात पेज पर, निर्णय के बगल में, कहता है।
अक्सर पूछे जाने वाले प्रश्न
क्या मैं बिना कुंजी के टोकन सत्यापित कर सकता हूँ?
नहीं — सत्यापन के लिए जारीकर्ता की सार्वजनिक कुंजी (या HMAC के लिए साझा रहस्य) चाहिए। डिकोडिंग के लिए कोई कुंजी नहीं चाहिए, और यही वह भ्रम है जिससे बचना है: डिकोड किया गया टोकन पठनीय है, सत्यापित नहीं। यदि जारीकर्ता JWKS प्रकाशित करता है, तो उसे well-known URL से फ़ेच करें और टोकन के kid से मिलाएँ; इस साइट का सत्यापनकर्ता यह काम आपके लिए करता है।
मेरा RS256 टोकन मेरे रहस्य से क्यों विफल होता है?
क्योंकि रहस्य और RSA कुंजी अलग परिवार हैं, और सही सत्यापनकर्ता उन्हें मिलाने से मना करता है। RS256 टोकन जारीकर्ता की RSA सार्वजनिक कुंजी — PEM, JWK या JWKS — से सत्यापित होते हैं, कभी पाठ रहस्य से नहीं। रहस्य का उपयोग करना ही एल्गोरिदम-कन्फ़्यूज़न हमला होगा: सार्वजनिक कुंजी सार्वजनिक है, इसलिए HMAC सत्यापन द्वारा उसे रहस्य मानने पर कोई भी टोकन जाली बना सकता था।
JWT कितने समय तक जीवित रहना चाहिए?
एक्सेस टोकनों के लिए मिनट, दिन नहीं: 5–15 मिनट आम सीमा है, दीर्घकालिक सत्र रीफ़्रेश टोकन के साथ। छोटी अवधि चुराए गए टोकन के नुकसान को उसकी समाप्ति से पहले की अवधि तक सीमित करती है, और रद्दीकरण को ब्लॉकलिस्ट बनाए रखने के बजाय फिर से जारी न करने का मामला बनाती है। हफ़्तों तक जीने वाले टोकन बदतर टूलींग वाले सत्र कुकीज़ हैं।