Daniel J. Bernstein की सुरक्षा-आधारित-डिज़ाइन अवधारणाओं का व्यावहारिक विश्लेषण—qmail से Curve25519 तक—और यह कि “सरल, सत्यापन-योग्य क्रिप्टो” व्यवहार में क्या मतलब रखता है।

सुरक्षा-आधारित-डिज़ाइन का मतलब है ऐसा सिस्टम बनाना कि आम गलतियाँ करना कठिन हो—और जो अनिवार्य गलतियाँ हों उनका नुकसान सीमित रहे। लंबे चेकलिस्ट पर निर्भर रहने ("X को validate करना, Y sanitize करना, Z कॉन्फ़िगर करना…") की बजाय आप सॉफ़्टवेयर को इस तरह डिज़ाइन करते हैं कि सबसे सुरक्षित रास्ता सबसे आसान रास्ता भी हो।
इसे बच्चे-सुरक्षा पैकेजिंग की तरह सोचिए: यह मानता है कि हर कोई परफेक्ट तरीके से सावधान नहीं रहेगा; लोग थके हुए, व्यस्त और कभी-कभी गलत होते हैं। अच्छा डिज़ाइन डेवलपर्स, ऑपरेटरों और उपयोगकर्ताओं से जितनी "परफेक्ट बिहेवियर" की आवश्यकता है उसे घटा देता है।
सुरक्षा की समस्याएँ अक्सर जटिलता में छिपी होती हैं: बहुत सारे फीचर, बहुत सारे ऑप्शन, कंपोनेंट्स के बीच बहुत सारी अंतःक्रियाएँ। हर अतिरिक्त नॉब एक नया फेल्योर मोड पैदा कर सकता है—सिस्टम टूटने या गलत उपयोग होने का एक अप्रत्याशित तरीका।
सादगी दो व्यावहारिक तरीकों से मदद करती है:
यह अपनी जगह का न्यूनवाद नहीं है। यह व्यवहारों के सेट को इतना छोटा रखने के बारे में है कि आप इसे वास्तव में समझ सकें, टेस्ट कर सकें, और यह सोच सकें कि कुछ गलत होने पर क्या होता है।
यह पोस्ट Daniel J. Bernstein (DJB) के काम को सुरक्षा-आधारित-डिज़ाइन के ठोस उदाहरणों के रूप में उपयोग करती है: कैसे qmail ने फेल्योर मोड्स घटाने की कोशिश की, कैसे constant-time सोच अदृश्य रिसाव से बचाती है, और कैसे Curve25519/X25519 और NaCl ऐसे क्रिप्टो की ओर बढ़ते हैं जिन्हें गलत उपयोग करना कठिन हो।
यह क्या नहीं करेगी: क्रिप्टोग्राफी का पूरा इतिहास देना, एल्गोरिद्म का प्रमाणित सुरक्षा प्रमाण दिखाना, या यह दावा करना कि हर प्रोडक्ट के लिए एक "सबसे अच्छा" लाइब्रेरी है। और यह यह भी नहीं कहेगी कि अच्छे प्रिमिटिव सब कुछ सुलझा देते हैं—असली सिस्टम अब भी की-हैंडलिंग, इंटीग्रेशन त्रुटियों और ऑपरेशनल गैप्स के कारण फेल होते हैं।
लक्ष्य सरल है: डिज़ाइन पैटर्न दिखाना जो सुरक्षित परिणामों की संभावना बढ़ाते हैं, भले ही आप क्रिप्टोग्राफी विशेषज्ञ न हों।
Daniel J. Bernstein (अक्सर “DJB”) एक गणितज्ञ और कंप्यूटर वैज्ञानिक हैं जिनका काम व्यावहारिक सुरक्षा इंजीनियरिंग में बार-बार दिखता है: ईमेल सिस्टम (qmail), क्रिप्टोग्राफिक प्रिमिटिव और प्रोटोकॉल (विशेषकर Curve25519/X25519), और लाइब्रेरियाँ जो क्रिप्टो को वास्तविक दुनिया के उपयोग के लिए पैकेज करती हैं (NaCl)।
लोग DJB का हवाला इसलिए देते हैं क्योंकि उनके प्रोजेक्ट्स में एक सुसंगत इंजीनियरिंग प्रवृत्ति दिखती है जो चीज़ों के गलत होने के तरीकों की संख्या घटाती है।
एक आवर्ती विषय है छोटे, सख्त इंटरफेस। अगर एक सिस्टम कम एंट्री-पॉइंट और कम कॉन्फ़िगरेशन विकल्प उजागर करता है, तो उसे रिव्यू करना आसान है, टेस्ट करना आसान है, और गलती से गलत उपयोग करना कठिन है।
एक और विषय है स्पष्ट अनुमानों का दस्तावेजीकरण। सुरक्षा विफलताएँ अक्सर अनकहे हुए अपेक्षाओं से आती हैं—रैन्डमनेस, टाइमिंग बिहेवियर, एरर हैंडलिंग, या कीज़ कैसे स्टोर की जाती हैं। DJB की लेखन शैली और इम्प्लीमेंटेशन आम तौर पर खतरे के मॉडल को ठोस बनाते हैं: क्या सुरक्षित है, किससे, और किन परिस्थितियों में।
अंत में, वहाँ सुरक्षित डिफ़ॉल्ट्स और बोरिंग करेक्टनेस की ओर झुकाव है। इस परंपरा में कई डिज़ाइनों का प्रयास तीखे किनारों को खत्म करना है जो सूक्ष्म बग्स की ओर ले जाते हैं: अस्पष्ट पैरामीटर, वैकल्पिक मोड्स, और प्रदर्शन-शॉर्टकट जो जानकारी लीक करते हैं।
यह लेख जीवन-कथा या व्यक्तित्वों पर बहस नहीं है। यह एक इंजीनियरिंग पढ़ है: qmail, constant-time सोच, Curve25519/X25519, और NaCl में आप कौन से पैटर्न देख सकते हैं और वे पैटर्न सिस्टम को कैसे सरल बनाकर उत्पादन में कम नाज़ुक बनाते हैं।
qmail को एक बहुत ही अवांछनीय समस्या हल करने के लिए बनाया गया था: ईमेल भरोसेमंद ढंग से डिलीवर करना जबकि मेल सर्वर को एक हाई-वाल्यू टार्गेट माना जाए। मेल सिस्टम इंटरनेट पर रहते हैं, दिनभर शत्रुतापूर्ण इनपुट स्वीकार करते हैं, और संवेदनशील डेटा (मेसेज, क्रेडेंशियल्स, राउटिंग रूल्स) को छूते हैं। ऐतिहासिक रूप से, एक बग एक मोनोलीथिक मेल डेमन में पूरे सिस्टम का समझौता कर सकता था—या संदेश चुपचाप खो सकते थे जिसे तब तक नोटिस न किया जाए जब तक बहुत देर न हो जाए।
qmail का एक परिभाषित विचार है कि "मेल डिलीवरी" को छोटे-छोटे प्रोग्रामों में तोड़ा जाए जो हर एक अपना काम करते हैं: रिसीविंग, क्यूइंग, लोकल डिलीवरी, रिमोट डिलीवरी आदि। हर हिस्से का इंटरफ़ेस संकीर्ण और जिम्मेदारियाँ सीमित होती हैं।
यह अलगाव इसलिए महत्वपूर्ण है क्योंकि फेलियर्स लोकेल हो जाते हैं:
यह सुरक्षा-आधारित-डिज़ाइन का एक व्यावहारिक रूप है: सिस्टम को इस तरह डिज़ाइन करें कि "एक गलती" का अर्थ "कुल विफलता" बनना कम सम्भव हो।
qmail उन आदतों का मॉडल भी देता है जो ईमेल से परे अच्छी तरह काम आती हैं:
निष्कर्ष यह नहीं है कि "qmail का उपयोग करें"। यह है कि अक्सर आप ज़्यादा कोड लिखने या और नॉब जोड़ने से पहले कम फेल्योर मोड के आसपास फिर से डिज़ाइन करके बड़े सुरक्षा लाभ पा सकते हैं।
"Attack surface" उन सभी जगहों का योग है जहाँ आपका सिस्टम छेड़ा, झकझोड़ा, या गलत करने के लिए ट्रिक किया जा सकता है। एक उपयोगी उपमा घर है: हर दरवाज़ा, खिड़की, गैरेज ओपनर, स्पेयर की और डिलीवरी स्लॉट एक संभावित प्रवेश बिंदु है। आप बेहतर ताले लगा सकते हैं, लेकिन कम प्रवेश बिंदुओं से सुरक्षा भी बढ़ती है।
सॉफ्टवेयर भी ऐसा ही है। आप जितने अधिक पोर्ट खोलेंगे, फ़ाइल फ़ॉर्मैट स्वीकार करेंगे, एडमिन एंडपॉइंट उजागर करेंगे, कॉन्फ़िगरेशन नॉब जोड़ेंगे, और प्लगइन हुक सपोर्ट करेंगे, उतने अधिक तरीके चीज़ें फेल हो सकती हैं।
एक "टाइट इंटरफेस" ऐसा API है जो कम करता है, कम वैरिएशन स्वीकार करता है, और अस्पष्ट इनपुट को इनकार कर देता है। यह अक्सर प्रतिबंधात्मक लगता है—लेकिन इसे सुरक्षित करना आसान होता है क्योंकि ऑडिट करने के लिए कम कोड पाथ होते हैं और कम आश्चर्यजनक इंटरैक्शन रहते हैं।
दो डिज़ाइनों पर विचार कीजिए:
दूसरा डिज़ाइन अटैकर के द्वारा मैनिपुलेट किए जाने योग्य चीज़ों को घटा देता है। यह आपकी टीम के द्वारा गलती से गलत कॉन्फ़िगर करने की गुंजाइश को भी घटाता है।
विकल्प टेस्टिंग को गुणा करते हैं। अगर आप 10 टॉगल सपोर्ट करते हैं, तो आपके पास 10 व्यवहार नहीं होते—आपके पास संयोजन होते हैं। कई सुरक्षा बग उन सीमाओं में रहते हैं: "यह फ़्लैग चेक को डिसेबल कर देता है," "यह मोड वैलिडेशन को स्किप करता है," "यह लेगेसी सेटिंग रेट लिमिट्स को बायपास करती है।" टाइट इंटरफेस "अपनी-चुनें-खुद की-रोमांच सुरक्षा" को एक स्पष्ट, रोशनी वाली पथ में बदल देते हैं।
इसका उपयोग अटैक-सर्फेस को पहचानने के लिए करें जो चुपचाप बढ़ता है:
जब आप इंटरफेस कम नहीं कर सकते, तो उसे सख्त बनाइए: जल्दी validate कीजिए, अनजान फील्ड्स reject कीजिए, और "पावर फीचर्स" को अलग, स्पष्ट स्कोप वाले एंडपॉइंट के पीछे रखिए।
"कॉनस्टेंट-टाइम" व्यवहार का मतलब है कि एक गणना का समय (लगभग) सीक्रेट वैल्यूज़ जैसे प्राइवेट कीज़, नॉन्स, या मध्यवर्ती बिट्स के बावजूद समान रहता है। लक्ष्य तेज़ होना नहीं है; यह "उजागर न होने वाला" होना है: अगर अटैकर रनटाइम को सीक्रेट्स से जोड़ नहीं पाता, तो वे उन सीक्रेट्स को अवलोकन द्वारा निकालना बहुत कठिन पाते हैं।
टाइमिंग लीक इसलिए मायने रखते हैं क्योंकि अटैकरों को हमेशा मैथ को तोड़ने की जरूरत नहीं होती। अगर वे एक ऑपरेशन को कई बार चला सकते हैं (या शेयर किए गए हार्डवेयर पर उसे देख सकते हैं), तो सूक्ष्म अंतर—माइक्रोसेकंड्स, नैनोसेकंड्स, यहाँ तक कि कैश प्रभाव—ऐसे पैटर्न प्रकट कर सकते हैं जो समय के साथ मिलकर की रिकवरी में बदल जाते हैं।
साधारण कोड भी डेटा के आधार पर अलग व्यवहार कर सकता है:
if (secret_bit) { ... } कंट्रोल फ्लो और अक्सर रनटाइम बदल देता है।आपको असेंबली पढ़ने की ज़रूरत नहीं है ताकि ऑडिट से मूल्य मिले:
if स्टेटमेंट्स, एरे इंडेक्स, सीक्रेट-आधारित टर्मिनेशन वाले लूप, और "fast path/slow path" लॉजिक।कॉनस्टेंट-टाइम सोच हीरोइक्स के बारे में नहीं बल्कि अनुशासन के बारे में है: कोड इस तरह डिज़ाइन कीजिए कि सीक्रेट्स टाइमिंग को प्रभावित ही न कर सकें।
एलिप्टिक-कर्व की कुंजी-एक्सचेंज दो उपकरणों के बीच वही साझा सीक्रेट बनाने का तरीका है जबकि वे केवल "पब्लिक" संदेश नेटवर्क पर भेजते हैं। हर पक्ष एक प्राइवेट वैल्यू बनाता है (गोपनीय) और एक संबंधित पब्लिक वैल्यू (जो भेजने पर सुरक्षित है)। सार्वजनिक वैल्यूज़ के आदान-प्रदान के बाद, दोनों पक्ष अपने निजी मूल्य को दूसरे पक्ष की सार्वजनिक वैल्यू के साथ मिलाकर एक समान साझा सीक्रेट पर पहुँचते हैं। एक ईव्सड्रॉपर सार्वजनिक वैल्यूज़ देखता है लेकिन व्यावहारिक रूप से साझा सीक्रेट पुनर्निर्मित नहीं कर सकता, इसलिए दोनों पार्टियाँ उसके आधार पर संकेतक कुंजियाँ निकालकर निजी रूप से बात कर सकती हैं।
Curve25519 आधारभूत कर्व है; X25519 उस पर बना मानकीकृत, "विशिष्ट कार्य करें" key-exchange फ़ंक्शन है। इनका आकर्षण मुख्यतः सुरक्षा-आधारित-डिज़ाइन में है: कम फूट-गन्स, कम पैरामीटर विकल्प, और कम तरीके जिससे आप गलती से असुरक्षित सेटिंग चुन लें।
ये कई तरह के हार्डवेयर पर तेज़ भी हैं, जो सर्वरों के लिए कई कनेक्शन संभालने और फ़ोन की बैटरी बचाने दोनों के लिए मायने रखता है। और डिज़ाइन ऐसे इम्प्लीमेंटेशन को प्रेरित करती है जिन्हें कॉन्स्टेंट-टाइम बनाए रखना आसान है (जिससे टाइमिंग अटैक्स के खिलाफ प्रतिरोध बढ़ता है), जो जोखिम को घटाता है कि कोई चालाक अटैकर छोटी परफ़ॉर्मेंस डिफरेंस नापकर सीक्रेट निकाल ले।
X25519 आपको कुंजी-सहमति देता है: यह दो पार्टियों को साझा सीक्रेट तैयार करने में मदद करता है ताकि वे सममित एन्क्रिप्शन के लिए कुंजियाँ निकाल सकें।
यह अपने आप ऑथेंटिकेशन नहीं देता। अगर आप X25519 को बिना यह सत्यापित किए चला रहे हैं कि आप किससे बात कर रहे हैं (उदा., सर्टिफिकेट, सिग्नेचर, या प्री-शेयर्ड की के साथ), तो आपको अभी भी गलत पार्टी से जुड़ने का खतरा हो सकता है। दूसरे शब्दों में: X25519 ईव्सड्रॉपिंग से बचाने में मदद करता है, पर खुद अकेले impersonation नहीं रोकता।
NaCl ("Networking and Cryptography library") का निर्माण एक सरल लक्ष्य के चारों ओर हुआ: एप्लिकेशन डेवलपर्स के लिए गलती से अनसुरक्षित क्रिप्टोग्राफी जोडऩा कठिन बनाना। अलग-अलग एल्गोरिद्म, मोड, पैडिंग नियम, और कॉन्फ़िगरेशन नॉब्स की बुफे पेश करने के बजाय, NaCl आपको उच्च-स्तरीय ऑपरेशन्स की एक छोटी सेट की ओर धकेलता है जो पहले से ही सुरक्षित तरीक़े से वायर्ड हैं।
NaCl के APIs नाम बताते हैं कि आप क्या करना चाहते हैं, न कि आप किन प्रिमिटिव्स को जोड़ना चाहते हैं।
crypto_box (“box”): पब्लिक-की ऑथेंटिकेटेड एनक्रिप्शन। आप अपनी प्राइवेट की, रिसीवर की पब्लिक की, एक nonce और मेसेज देते हैं। आपको एक सिफरटेक्स्ट मिलता है जो (a) मेसेज छिपाता है और (b) प्रमाण देता है कि यह उसी ने भेजा जिसने सही की जाना था।crypto_secretbox (“secretbox”): साझा-की ऑथेंटिकेटेड एनक्रिप्शन। विचार समान है, पर एक साझा सीक्रेट की के साथ।मुख्य लाभ यह है कि आप अलग से "एनक्रिप्शन मोड" और "MAC एल्गोरिथ्म" नहीं चुनते और फिर उम्मीद करते हैं कि आपने सही तरीके से जोड़ा। NaCl के डिफ़ॉल्ट आधुनिक, misuse-प्रतिरोधी संयोजनों (encrypt-then-authenticate) को लागू करते हैं, इसलिए सामान्य विफल मोड—जैसे इंटीग्रिटी चेक भूल जाना—काफी कम हो जाते हैं।
NaCl की सख्ती सीमित महसूस हो सकती है अगर आपको लेगेसी प्रोटोकॉल, विशिष्ट फॉर्मैट, या नियम-आधारित एल्गोरिद्म के साथ संगतता चाहिए। आप "मैं हर पैरामीटर ट्वीक कर सकता हूँ" के बदले "मैं कुछ ऐसा भेज सकता हूँ जो बिना क्रिप्टो विशेषज्ञ बने सुरक्षित हो" चुन रहे हैं।
कई प्रोडक्ट्स के लिए यही बात मायने रखती है: डिज़ाइन स्पेस को सीमित करिए ताकि आरंभ से ही कम बग मौजूद हों। अगर वास्तव में कस्टमाइज़ेशन चाहिए, तो आप निचले-लेवल प्रिमिटिव्स का उपयोग कर सकते हैं—पर आप फिर से तीखे किनारों के अंदर जा रहे हैं।
"डिफ़ॉल्ट में सुरक्षित" का मतलब है कि जब आप कुछ नहीं करते तो सबसे सुरक्षित, सबसे तार्किक विकल्प ही मिलता है। अगर डेवलपर एक लाइब्रेरी इंस्टॉल करता है, एक त्वरित उदाहरण कॉपी करता है, या फ्रेमवर्क डिफ़ॉल्ट्स का उपयोग करता है, तो परिणाम होना चाहिए कि उसे गलत उपयोग करना कठिन हो और गलती से कमजोर बनाना मुश्किल हो।
डिफ़ॉल्ट मायने रखते हैं क्योंकि अधिकांश वास्तविक सिस्टम उन्हीं पर चलते हैं। टीमें तेज़ी से बढ़ती हैं, डॉ큐मेंटेशन को हल्के में पढ़ा जाता है, और कॉन्फ़िगरेशन धीरे-धीरे बढ़ता है। अगर डिफ़ॉल्ट "लचीला" है, तो अक्सर इसका अर्थ है "गलत कॉन्फ़िगर करना आसान"।
क्रिप्टो_FAILURES हमेशा "खराब गणित" से नहीं होते। वे अक्सर खतरनाक सेटिंग चुनने से होते हैं क्योंकि वह उपलब्ध थी, परिचित थी, या आसान थी।
सामान्य डिफ़ॉल्ट जाल:
ऐसे स्टैक्स पसंद करें जो सुरक्षित रास्ते को सबसे आसान बनाते हों: विवेचित प्रिमिटिव्स, रूढ़िवादी पैरामीटर, और ऐसे APIs जो आपसे नाजुक निर्णय न माँगें। अगर एक लाइब्रेरी आपसे दस एल्गोरिद्म, पाँच मोड, और कई एनकोडिंग चुनने को कहती है, तो आप कॉन्फ़िगरेशन द्वारा सुरक्षा इंजीनियरिंग कर रहे हैं।
जब संभव हो, उन लाइब्रेरियों और डिज़ाइनों का चयन करें जो:
सुरक्षा-आधारित-डिज़ाइन का एक हिस्सा हर निर्णय को एक ड्रॉपडाउन में बदलने से इनकार करना भी है।
"सत्यापन-योग्य" का अर्थ अधिकांश प्रोडक्ट टीमों में "फॉर्मली प्रूव्ड" नहीं होता। इसका मतलब है कि आप जल्दी, बार-बार, और कम गलतफहमी के साथ विश्वास बना सकते हैं कि कोड क्या कर रहा है।
एक कोडबेस तब अधिक सत्यापन-योग्य बनता है जब:
हर ब्रांच, मोड, और ऑप्शनल फीचर वह समीक्षा करने वालों को जो चीज़ें समझनी पड़ती हैं, गुणा कर देता है। सरल इंटरफेस संभावित अवस्थाओं को संकुचित कर देते हैं, जो समीक्षा गुणवत्ता को दो तरह बेहतर करता है:
इसे उबाऊ और दोहराने योग्य रखिए:
यह संयोजन विशेषज्ञ समीक्षा की जगह नहीं लेगा, पर यह फर्श उठाता है: कम आश्चर्य, तेज़ पता लगाना, और ऐसा कोड जिसे आप वास्तव में समझ सकें।
भले ही आप X25519 जैसे अच्छी-खासी प्रिमिटिव चुनें या NaCl-शैली के छोटे API इस्तेमाल करें, सिस्टम तब भी फेल होते हैं जहां चीज़ें गंदगी भरी होती हैं: इंटीग्रेशन, एनकोडिंग, और ऑपरेशन। अधिकांश वास्तविक दुनिया की घटनाएँ "गणित गलत था" नहीं होतीं, बल्कि "गणित का गलत उपयोग हुआ"।
की-हैंडलिंग गलतियाँ सामान्य हैं: दीर्घकालिक कीज़ का पुन: उपयोग जहाँ अस्थायी की अपेक्षित है, स्रोत नियंत्रण में कीज़ स्टोर होना, या "पब्लिक की" और "सीक्रेट की" बाइट स्ट्रिंग्स के बीच भ्रम क्योंकि वे दोनों बस एरेज़ हैं।
Nonce misuse एक बार-बार होने वाला अपराधी है। कई ऑथेंटिकेटेड-एनक्रिप्शन स्कीमों को हर की के लिए अनूठा nonce चाहिए। एक nonce डुप्लिकेट कर दीजिए (अक्सर काउंटर रिसेट, मल्टी-प्रोसेस रेस, या "पर्याप्त रैंडम" मान लेने की वजह से), और आप गोपनीयता या इंटीग्रिटी खो सकते हैं।
एनकोडिंग और पार्सिंग समस्याएँ चुपचाप फेल्योर पैदा करती हैं: base64 बनाम hex भ्रम, लीडिंग जीरो का गिरना, असंगत endianness, या कई एनकोडिंग स्वीकार करना जो अलग तरह से तुल्यांकन करते हैं। ये बग "वेरिफाइड सिगनेचर" को "किसी और चीज़ ने वेरिफाइ कर लिया" बना सकते हैं।
एरर हैंडलिंग दोनों दिशाओं में खतरनाक हो सकती है: बहुत डिटेल वाला एरर अटैकर की मदद करता है, या वेरिफिकेशन विफल होते हुए भी आगे बढ़ना खतरनाक है।
सीक्रेट्स लॉग्स, क्रैश रिपोर्ट्स, एनालिटिक्स, और डिबग एंडपॉइंट्स के माध्यम से लीक होते हैं। कीज़ बैकअप्स, VM इमेजेज़, और बहुत व्यापक रूप से साझा किए गए environment variables में भी पहुँच जाती हैं। साथ ही, निर्भरताओं के अपडेट (या उनका अभाव) आपको किसी संवेदनशील इम्प्लिमेंटेशन पर पक्के तौर पर छोड़ सकते हैं भले ही डिज़ाइन अच्छा था।
अच्छे प्रिमिटिव अपने आप सुरक्षित प्रोडक्ट नहीं बनाते। आप जितने ज़्यादा विकल्प उजागर करेंगे—मोड्स, पैडिंग्स, एनकोडिंग, कस्टम "ट्वीक्स"—उतने ज़्यादा तरीके आपकी टीम गलती से कुछ भंगुर बना सकती है। सुरक्षा-आधारित-डिज़ाइन का दृष्टिकोण यह शुरू करता है कि एक इंजीनियरिंग पथ चुनें जो निर्णय-बिंदुओं को घटा दे।
एक उच्च-स्तरीय लाइब्रेरी (one-shot APIs जैसे "इस रिसीवर के लिए यह मैसेज एन्क्रिप्ट करो") का उपयोग करें जब:
निचले-लेवल प्रिमिटिव्स (AEADs, हैशेस, कुंजी-एक्सचेंज) तभी मिलाकर प्रयोग करें जब:
एक उपयोगी नियम: अगर आपकी डिज़ाइन डॉक में "हम मोड बाद में चुनेंगे" या "हम नॉन्स का बस ध्यान रखेंगे" लिखा है, तो आप पहले ही बहुत सारे नॉब्स की कीमत चुका रहे हैं।
विपणन भाषा नहीं, ठोस उत्तर माँगिए:
क्रिप्टो को safety-critical कोड की तरह ट्रीट करें: API सतह छोटी रखें, वर्शन पिन करें, प्रिमिटिव्स के लिए known-answer टेस्ट जोड़ें, और पार्सिंग/सीरियलाइज़ेशन पर फज़िंग चलाइए। उन चीज़ों को दस्तावेज़ करें जिन्हें आप नहीं सपोर्ट करेंगे (एल्गोरिद्म, लेगेसी फॉर्मैट), और "कम्पैटिबिलिटी स्विचेस" के बजाय माइग्रेशन बनाइए जो हमेशा के लिए टिका न रहें।
सुरक्षा-आधारित-डिज़ाइन कोई नया टूल नहीं है जिसे आप खरीद लें—यह आदतों का एक सेट है जो बग की पूरी श्रेणियों को बनाना कठिन बनाता है। DJB-शैली इंजीनियरिंग में आम धागा है: चीज़ों को इतना सरल रखें कि उन पर तर्क किया जा सके, इंटरफेस इतने टाइट रखें कि गलत उपयोग न हो, ऐसा कोड लिखें जो हमला होने पर भी समान व्यवहार करे, और ऐसे डिफ़ॉल्ट चुनें जो सुरक्षित विफल हों।
यदि आप इन चरणों के लिए एक संरचित चेकलिस्ट चाहते हैं, तो अपने सुरक्षा डॉक्स के साथ एक आंतरिक "क्रिप्टो इन्वेंटरी" पेज जोड़ने पर विचार करें (उदा., /security)।
ये विचार केवल क्रिप्टो लाइब्रेरियों तक सीमित नहीं हैं—वे उस तरीके पर भी लागू होते हैं जिससे आप सॉफ़्टवेयर बनाते और भेजते हैं। यदि आप किसी vibe-coding वर्कफ़्लो (उदा., Koder.ai) का उपयोग कर रहे हैं जहाँ आप चैट के माध्यम से वेब/सर्वर/मोबाइल ऐप बनाते हैं, तो वही सिद्धांत प्रोडक्ट प्रतिबंधों के रूप में प्रकट होते हैं: सीमित स्टैक्स रखना (वेब पर React, बैकएंड पर Go + PostgreSQL, मोबाइल पर Flutter), जेनरेशन से पहले योजना पर जोर देना, और रोलबैक सस्ता बनाना।
व्यवहार में, ऐसे फीचर जैसे planning mode, snapshots और rollback, और source code export गलतियों के "blast radius" को घटाते हैं: आप परिवर्तनों के लैंड होने से पहले इरादा रिव्यू कर सकते हैं, कुछ गलत होने पर जल्दी revert कर सकते हैं, और सत्यापित कर सकते हैं कि जो चल रहा है वही जेनरेट हुआ था। यह qmail के compartmentalization जैसा ही सुरक्षा-आधारित-डिज़ाइन का इन्स्टिंक है—आधुनिक डिलिवरी पाइपलाइनों पर लागू।
Security-by-construction का अर्थ ऐसा सॉफ़्टवेयर डिजाइन करना है कि सबसे सुरक्षित रास्ता वही सबसे आसान रास्ता भी हो। लंबी चेकलिस्ट पर लोगों के भरोसे रहने के बजाय आप सिस्टम को इस तरह सीमित करते हैं कि सामान्य गलतियाँ करना मुश्किल हो और जो गलतियाँ हों उनका प्रभाव कम से कम हो (छोटी “blast radius”)।
जटिलता छुपी हुई अंतःक्रियाओं और किनारों (edge cases) को जन्म देती है जिन्हें टेस्ट करना मुश्किल और गलत कॉन्फ़िगर करना आसान होता है।
व्यवहारिक रूप से सादगी से मिलने वाले फायदे:
एक tight interface कम काम करता है और कम वैरिएशन स्वीकार करता है। यह अस्पष्ट इनपुट से बचता है और उन वैकल्पिक मोड्स को घटाता है जो “कॉन्फ़िगरेशन से सुरक्षा” बनाते हैं।
व्यवहारिक तरीका:
qmail मेल हैंडलिंग को छोटे-छोटे प्रोग्रामों (receive, queue, deliver आदि) में बाँट देता है, जिनकी सीमित जिम्मेदारियाँ होती हैं। इससे फायदे हैं:
कॉनस्टेंट-टाइम व्यवहार का लक्ष्य रनटाइम (और अक्सर मेमोरी एक्सेस पैटर्न) को सीक्रेट वैल्यूज से स्वतंत्र बनाना है। यह महत्वपूर्ण है क्योंकि अटैकर कई बार गणित को नहीं तोड़कर बल्कि समय मापकर, कैश इफेक्ट्स देखकर या fast-path/slow-path के अंतर से सीक्रेट निकाल लेते हैं।
यह केवल मजबूत एल्गोरिद्म चुनने का मामला नहीं है—यह "नज़रअंदाज़ किये जा सकने वाले रिसाव" को रोकने के बारे में है।
शुरू में पहचानिए कि क्या गोपनीय है (प्राइवेट कीज़, साझा सीक्रेट्स, MAC कीज़, ऑथ टैग्स), फिर देखिए कि ये कहां फ़्लो होते हैं और क्या वे कंट्रोल-फ्लो या मेमोरी-एक्सेस को प्रभावित करते हैं।
रेड फ्लैग्स:
if ब्रांचेससाथ ही अपने क्रिप्टो डिपेंडेंसी से पुष्टि करें कि वह अपेक्षित ऑपरेशन्स के लिए constant-time व्यवहार का दावा करता है।
X25519, Curve25519 पर बना एक मानकीकृत key-agreement फ़ंक्शन है। इसे पसंद किए जाने के कारणों में हैं: कम पैरामीटर चुनने की जरूरत, अच्छा प्रदर्शन, और ऐसे इम्प्लीमेंटेशन के लिए डिज़ाइन जो constant-time बनाए रखना आसान करते हैं—इससे misuse की संभावना घटती है।
यह एक सुरक्षित "डिफ़ॉल्ट लेन" के रूप में उपयोग करने लायक है—बशर्ते आप अभी भी ऑथेंटिकेशन और की-मैनेजमेंट सही रखें।
नहीं। X25519 केवल key agreement देता है—यह तय नहीं करता कि आप किसके साथ बोल रहे हैं। impersonation रोकने के लिए इसे ऑथेंटिकेशन के साथ जोड़िए, जैसे:
बिना ऑथेंटिकेशन के आप "गलत पार्टी" के साथ भी सुरक्षित रूप से बातचीत कर सकते हैं।
NaCl ऐसे हाई-लेवल ऑपरेशन्स देता है जिन्हें पहले से सुरक्षित तरीके से जोड़ा गया है, बजाय इसके कि डेवलपर अलग-अलग एल्गोरिद्म, मोड और पैडिंग जोड़कर खुद संयोजन करें।
आम बिल्डिंग ब्लॉक्स:
crypto_box: पब्लिक-की ऑथेंटिकेटेड एनक्रिप्शन (आपकी प्राइवेट की + रिसीवर की पब्लिक की + nonce + मेसेज → ciphertext)crypto_secretbox: साझा-की ऑथेंटिकेटेड एनक्रिप्शनप्रायोगिक लाभ: आप अलग से "एनक्रिप्ट तो कर दिया, लेकिन इंटीग्रिटी भूल गया" जैसी कॉम्पोजिशन गलतियों से बच जाते हैं।
अच्छे प्रिमिटिव होने पर भी असफलताएँ तब होती हैं जब इंटीग्रेशन और ऑपरेशंस ढीले हों। सामान्य गलती वाले मामले:
रोकथाम: