c मैं लिबसोडियम का सही उपयोग कैसे कर सकता हूं ताकि यह संस्करणों के बीच संगत हो?




cryptography compatibility (2)

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

सोडियम के वर्तमान संस्करण के लिए, हस्ताक्षर एड25519 एल्गोरिथम का उपयोग करते हुए किया जाता है। मैं सोचता हूं कि मूलभूत आदिम सॉडियन के नए संस्करणों में बदल सकता है (अन्यथा लिब्सोडियम किसी विशेष को चुनने का एक तरीका नहीं दिखाएगा, मुझे लगता है)।

क्या मैं...

  1. हमेशा डिफ़ॉल्ट आदिम (यानी crypto_sign ) का उपयोग करें
  2. एक विशिष्ट आदिम (यानी crypto_sign_ed25519 ) का उपयोग करें
  3. क्या करें (1), लेकिन फ़ाइल में sodium_library_version_major() के मूल्य को sodium_library_version_major() या तो एक समर्पित 'सोडियम संस्करण' फ़ील्ड या सामान्य 'फ़ाइल प्रारूप संशोधन' फ़ील्ड में) और अगर मौजूदा संस्करण चल रहा है तो छोड़ दें
  4. करो (3), लेकिन crypto_sign_primitive() भी स्टोर crypto_sign_primitive()
  5. करो (4), लेकिन crypto_sign_bytes() और दोस्तों को भी स्टोर करें

... या मुझे पूरी तरह से कुछ करना चाहिए?

मेरा प्रोग्राम सी में लिखा जाएगा।


सबसे पहले संभव समस्याओं के सेट की पहचान करें और फिर इसे हल करने का प्रयास करें। हमारे पास कुछ डेटा (एक रिकॉर्ड) और एक हस्ताक्षर है। हस्ताक्षर विभिन्न एल्गोरिदम के साथ गणना किया जा सकता है। कार्यक्रम इसके व्यवहार विकसित और बदल सकता है, लिबोडियम भी (स्वतंत्र रूप से) विकसित हो सकता है और इसके व्यवहार को बदल सकता है। हस्ताक्षर पीढ़ी के सामने हम हैं:

  • crypto_sign() , जो हस्ताक्षर करने के लिए कुछ डिफ़ॉल्ट एल्गोरिथ्म का उपयोग करता है (लेखन के समय में केवल crypto_sign_ed25519() आमंत्रित करता है)
  • crypto_sign_ed25519() , जो विशिष्ट ed25519 एल्गोरिदम पर आधारित हस्ताक्षर का उत्पादन करता है

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

दो मुख्य विकल्पों पर एक नज़र डालें:

  1. हर समय crypto_sign_ed25519() का उपयोग करना और इसे कभी भी बदलना नहीं है। एक विकल्प का वह बुरा नहीं है, क्योंकि यह सरल है और जब तक कि crypto_sign_ed25519() libsodium में मौजूद है और अपने आउटपुट में स्थिर है, आपको इसके लिए स्थिर निश्चित आकार के हस्ताक्षर और शून्य प्रबंधन ओवरहेड के बारे में चिंता करने की कोई जरूरत नहीं है। बेशक, भविष्य में किसी को इस एल्गोरिथम के साथ कुछ भयानक समस्या मिल सकती है और यदि आप एल्गोरिथम को बदलने के लिए तैयार नहीं हैं जो आपके लिए भयानक समस्या का मतलब हो सकता है
  2. crypto_sign() का उपयोग करना इसके साथ हम अचानक कई समस्याएं हैं, क्योंकि एल्गोरिथ्म बदल सकता है, इसलिए आपको हस्ताक्षर के साथ कुछ मेटाडेटा संगृहीत करना चाहिए, जो कि प्रश्नों का एक समूह खोलता है:
    • स्टोर करने के लिए क्या?
    • क्या यह मेटाडेटा रिकॉर्ड स्तर या फ़ाइल-स्तर होना चाहिए?

दूसरे दृष्टिकोण के लिए हमारे कार्यों में क्या उल्लेख है?

  • sodium_library_version_major() हमें लाइब्रेरी एपीआई संस्करण को बताने के लिए एक फ़ंक्शन है। यह समर्थित / डिफ़ॉल्ट एल्गोरिदम में परिवर्तन से सीधे संबंधित नहीं है इसलिए यह हमारी समस्याओं के लिए बहुत कम उपयोग है
  • crypto_sign_primitive() एक ऐसा कार्य है जो crypto_sign() में उपयोग किए गए एल्गोरिदम की पहचान करने वाली स्ट्रिंग देता है। यह हमारे लिए क्या सही है, क्योंकि माना जाता है कि इसका उत्पादन ठीक उसी समय बदल जाएगा जब एल्गोरिदम बदल जाएगा।
  • crypto_sign_bytes() एक ऐसा कार्य है जो बाइट्स में crypto_sign() द्वारा निर्मित हस्ताक्षर का आकार देता है। यह हस्ताक्षर के लिए आवश्यक भंडारण की मात्रा का निर्धारण करने के लिए उपयोगी है, लेकिन एल्गोरिथ्म में बदलाव होने पर यह आसानी से एक ही रह सकता है, इसलिए यह मेटाडेटा नहीं है जिसे हमें स्पष्ट रूप से स्टोर करने की आवश्यकता है।

अब जब हमें पता है कि स्टोर करना है, तो संसाधित डेटा पर प्रोसेसिंग का सवाल है। आपको एल्गोरिथ्म नाम प्राप्त करने और मिलान सत्यापन फ़ंक्शन को लागू करने की आवश्यकता है। दुर्भाग्य से, जो मैं देखता हूं, लिब्सोडियम स्वतः एल्गोरिथम नाम (जैसे EVP_get_cipherbyname() नाम EVP_get_cipherbyname() या EVP_get_digestbyname() - EVP_get_digestbyname() openssl) में उचित कार्य प्राप्त करने का कोई आसान तरीका प्रदान नहीं करता है, इसलिए आपको स्वयं को बनाने की जरूरत है (जो निश्चित रूप से चाहिए अज्ञात नाम के लिए विफल) और अगर आपको स्वयं बनाना है तो पुस्तकालय से नाम के बजाय कुछ संख्यात्मक पहचानकर्ता स्टोर करना अधिक आसान होगा (हालांकि अधिक कोड)।

अब हम फ़ाइल-स्तर बनाम रिकॉर्ड-स्तर पर वापस आएं। यह हल करने के लिए कि पूछने के लिए एक और दो सवाल हैं - क्या आप किसी भी समय पुराने रिकॉर्ड के लिए नए हस्ताक्षर बना सकते हैं (यह तकनीकी तौर पर संभव है, यह नीति द्वारा अनुमत है) और क्या आपको पुरानी फाइलों में नए रिकॉर्ड जोड़ने की आवश्यकता है?

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

  • आपके हस्ताक्षर के लिए गतिशील-आकार का फ़ील्ड है
  • एल्गोरिथ्म (डायनामिक स्ट्रिंग फ़ील्ड या आंतरिक (आपके ऐप्लीकेशन के लिए) आईडी स्टोर करें) हस्ताक्षर के साथ हस्ताक्षर उत्पन्न करने के लिए उपयोग किया जाता है

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

अन्य विकल्प? ठीक है, crypto_sign() बारे में क्या खास है? यह है कि इसका व्यवहार आपके नियंत्रण में नहीं है, लिब्सोडियम डेवलपर्स आपके लिए एल्गोरिदम चुनते हैं (इसमें कोई संदेह नहीं है कि वे अच्छा चुनाव करते हैं), लेकिन अगर आपके पास फ़ाइल संरचना में कोई संस्करण जानकारी है (हस्ताक्षर विशिष्ट नहीं है, मेरा मतलब है) अपनी स्वयं की विशेष पसंद बनाकर और एक फाइल संस्करण के साथ एक और एक अन्य के साथ दूसरे एल्गोरिथ्म का उपयोग करना (निश्चित रूप से रूपांतरण कोड के साथ) फिर, यह धारणा के आधार पर भी है कि आप नए हस्ताक्षर बना सकते हैं और नीति द्वारा इसकी अनुमति है।

जो हमें दो ओर से मूल दो विकल्पों के बारे में crypto_sign_ed25519() कि क्या यह crypto_sign_ed25519() का उपयोग करते हुए सभी को करने की परेशानी के लायक है या नहीं। यह अधिकतर आपके कार्यक्रम के जीवन काल पर निर्भर करता है, शायद मैं कहूंगा (एक राय के रूप में) कि यदि वह 5 साल से कम है तो यह केवल एक विशेष एल्गोरिथ्म का उपयोग करना आसान होता है यदि यह आसानी से 10 साल से अधिक हो सकता है, तो नहीं, आपको वास्तव में एल्गोरिथम (और संभवत: पूरे क्रिप्टो लाइब्रेरी) परिवर्तनों को जीवित रहने में सक्षम होना चाहिए।


बस उच्च स्तरीय एपीआई का उपयोग करें

उच्च स्तरीय एपीआई से कार्य करने के लिए एक अलग एल्गोरिथ्म का इस्तेमाल नहीं किया जा रहा है बिना पुस्तकालय के प्रमुख संस्करण को टकराया जा रहा है।

लिब्सोडियम 1.xy में एकमात्र तोड़ने वाला बदलाव अपेक्षाकृत पदावनत / गैरकायदायी कार्यों को हटा सकता है (जो कि मौजूदा-वर्तमान-वर्तमान --enable-minimal स्विच से संकलित विज्ञप्ति में मौजूद नहीं है)। बाकी सब कुछ पिछड़े संगत होगा।

नए एल्गोरिदम को 1.xy संस्करणों में उच्च-स्तरीय रैपरर्स के बिना पेश किया जा सकता है, और लिब्बोडियम 2 में एक नए उच्च-स्तरीय एपीआई के माध्यम से स्थिर और उजागर किया जाएगा।

इसलिए, crypto_sign_ed25519() कॉल करने में परेशान मत करें बस crypto_sign() उपयोग करें





libsodium