मैंने हमेशा एक असेंबली पर हस्ताक्षर करने का उद्देश्य एक रनटाइम चेक होने के लिए समझा है ताकि यह सुनिश्चित किया जा सके कि कोड के उन्नयन विश्वसनीय स्रोत से आते हैं। प्रभावी रूप से वे इस तरह के परिदृश्य से बचने की कोशिश कर रहे हैं:
मैं कंपनी ए से एन्क्रिप्शन लाइब्रेरी खरीदता हूं, इसके तुरंत बाद कंपनी बी को मेरे ईमेल विवरण प्राप्त होते हैं और मुझे एक बड़ी सुरक्षा बग होने का दावा करते हुए असेंबली में एक मुफ्त अपग्रेड भेजता है कंपनी ए से ठीक करें जब यह वास्तव में मेरे कोड में एक छिपी हुई विधि को इंजेक्ट करता है जो सभी डेटा भेजता है जिसे मैं कंपनी बी के सर्वर पर एन्क्रिप्ट करने की कोशिश कर रहा था। यह मानते हुए कि मैं एक बेवकूफ हूं और अंधेरे से अपने आवेदन की बिन निर्देशिका में इस नए डीएल को जोड़ता हूं, यह तथ्य कि इस निजी कुंजी के साथ हस्ताक्षर नहीं किया गया था क्योंकि पुराने संस्करण को रनटाइम पर उठाया जाएगा जिससे मेरा अपवाद और मेरा डेटा सुरक्षित हो जाएगा।
इसलिए, मुझे कोई कारण नहीं है कि आप असेंबली के बाहर सार्वजनिक कुंजी प्रकाशित करेंगे क्योंकि यह गारंटी नहीं है कि मूल फ़ाइल एक विशिष्ट विक्रेता से आती है, केवल यह कि सभी बाद के संस्करण एक ही स्थान से आते हैं सबसे पहला।
Wikipedia वही बात कहता है (केवल काफी कम शब्दों में)।
संपादित इस स्पष्ट करने के प्रयास में अधिक जानकारी के जोड़ने के लिए ...
मुझे लगता है कि बात यह है कि पहली बार स्पष्ट किया जा करने की जरूरत है कि सार्वजनिक और निजी कुंजियों के जोड़े अद्वितीय हैं। इसका मतलब है कि सार्वजनिक कुंजी को जानना असेंबली को पुनर्निर्माण के लिए पर्याप्त जानकारी नहीं है, जिससे वह उसी हैश चेक पास कर सके।
तो उपयोगकर्ता जेड जो कंपनी ए से एन्क्रिप्शन लाइब्रेरी का उपयोग कर रहा है जो उसके अनुप्रयोग बिन फ़ोल्डर में है। ऐसा करने के लिए वह DLL इस प्रकार है संदर्भित कर रहा है: सार्वजनिक कुंजी के प्रयोजन के
Encryption, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bcd6707151635d07"
three benefits साथ हमें प्रदान करने जो मैं एक समय में एक संभाल करेंगे।
सबसे पहले, यह असेंबली के लिए एक अद्वितीय नाम प्रदान करता है - इससे हमें कोई अतिरिक्त सुरक्षा नहीं मिलती है, लेकिन सी स्टाइल डीएल नरक को रोकता है जहां दो अलग-अलग कंपनियां दो अलग-अलग पुस्तकालयों को रिलीज कर सकती हैं जिन्हें एंसीशन संस्करण 1.0.0.0 कहा जाता है और आप सक्षम नहीं होंगे उन्हें एक ही निर्देशिका में स्टोर करने के लिए क्योंकि उन्हें अलग करने का कोई तरीका नहीं है।
दूसरा, यह उस परिदृश्य को रोकता है जिसे मैंने अपनी मूल पोस्ट में उल्लिखित किया है। कंपनी बी के लिए एन्क्रिप्शन लाइब्रेरी का एक और संस्करण बनाना असंभव है जो संस्करण 1.0.0.0 भी है और इसकी एक ही सार्वजनिक कुंजी है (ताकि पूरा नाम मेल खाए और आप कंपनी ए के बजाए अपना कोड कॉल करेंगे)। वे ऐसा नहीं कर सकते हैं क्योंकि यदि उनकी सार्वजनिक कुंजी मेल खाती है तो निजी कुंजी भी मेल खाना चाहिए (क्योंकि प्रत्येक जोड़ी अद्वितीय है)। कंपनी ए की सुरक्षा समझौता करके वे निजी कुंजी प्राप्त करने का एकमात्र तरीका प्राप्त कर सकते हैं।
अंत में यह फ़ाइल की अखंडता सुनिश्चित करता है (या तो भ्रष्टाचार या दुर्भावनापूर्ण कोड इंजेक्शन के माध्यम से बदला जाता है)। डीएल को रनटाइम पर धोया जाता है (जब यह निजी होता है और एप्लिकेशन के बिन फ़ोल्डर में) या सार्वजनिक कुंजी का उपयोग करते समय समय (जब आप इसे जीएसी में डालते हैं) इंस्टॉल करते हैं और हैश की तुलना उस हैश से की जाती है जो निजी द्वारा encrpyted था कुंजी और असेंबली में संग्रहीत। This page में कुछ आरेख और अधिक जानकारी हैं। एक बार फिर नकली करने का एकमात्र तरीका इस हैश को निजी कुंजी जानना है।
तो, ऊपर वर्णित विशिष्ट परिदृश्य को कवर करने के लिए, यह दिखाएं कि मैं कंपनी बी एन्क्रिप्शन डीएल के दुर्भावनापूर्ण संस्करण के साथ उपयोगकर्ता जेड की आपूर्ति करने की कोशिश कर रहा हूं। मेरा पहला प्रयास केवल एन्क्रिप्शन और संस्करण 1.0.0.0 नाम के साथ अपना स्वयं का डीएल बनाना है और इसे अपनी खुद की कुंजी जोड़ी से साइन इन करना है। दुर्भाग्यवश मैं उपयोगकर्ता जेड के आवेदन में संदर्भ कोड नहीं बदल सकता, इसलिए यह पूर्ण नाम जांच में विफल रहता है और लोड नहीं होता है। "ठीक है," मैं अपने मूंछ को घुमाने के दौरान कहता हूं, "मैं कंपनी ए के मिलान के लिए बस अपनी असेंबली की सार्वजनिक कुंजी बदल दूंगा"। एक बार मैंने यह नाम चेक पास कर लिया है, लेकिन हैश चेक विफल हो जाएगा क्योंकि उपयोगकर्ता जेड का ऐप असेंबली में संग्रहीत हैश को डिक्रिप्ट करने में सक्षम नहीं होगा (जिसे कंपनी बी की निजी कुंजी से एन्क्रिप्ट किया गया था) सार्वजनिक कुंजी (कंपनी ए) जो आपूर्ति की गई है। इसलिए कंपनी बी के लिए लाइब्रेरी बनाने का एकमात्र तरीका कंपनी ए है जो कंपनी ए की निजी कुंजी जानना है। इन सुरक्षा जांच में से कोई भी कंपनी ए पर कहीं भी सार्वजनिक कुंजी को प्रकाशित करने पर असेंबली की मूल रिलीज में निर्भर नहीं है।
यह भी ध्यान रखें कि इन सुविधाओं के सभी सुनिश्चित नहीं है (और सुनिश्चित करने के लिए दावा नहीं करते हैं) है कि मूल विधानसभा से कंपनी एक आया था, कि इस तरह के Verisign या माइक्रोसॉफ्ट के Authenticode सेवा के रूप में अन्य प्रणालियों द्वारा नियंत्रित किया जाता है, वे केवल यह सुनिश्चित एक बार जब आप असेंबली का संदर्भ लेते हैं तो केवल कंपनी ए उस कोड में बदलाव कर सकता है।
यह पूरी तरह से अस्पष्ट है और लिंक्ड आलेख में स्पष्ट रूप से उल्लेख नहीं किया गया है।ऐसा करने के लिए रनटाइम को प्रत्येक असेंबली के हैंश को कैश करने की आवश्यकता होती है और यह सत्यापित होता है कि असेंबली लोड करते समय। क्या यह वास्तव में ऐसा करता है? – sharptooth
जेफ़री रिचटर द्वारा "सीएलआर के माध्यम से सी #" के अनुसार यह तब होता है जब असेंबली जीएसी में नहीं होती है। पुस्तक से उद्धरण: "जब गठबंधन नामक असेंबली को जीएसी के अलावा किसी अन्य स्थान से लोड किया जाता है, तो सीएलआर असेंबली लोड होने पर हैश मानों की तुलना करता है। दूसरे शब्दों में जब भी एप्लिकेशन निष्पादित होता है और असेंबली लोड करता है तो फाइल का हैश किया जाता है यह प्रदर्शन हिट निश्चित रूप से यह सुनिश्चित करने के लिए एक ट्रेडऑफ है कि असेंबली फ़ाइल की सामग्री को छेड़छाड़ नहीं हुई है। " –
मैं इस उद्धरण को "सी # सीएलआर के माध्यम से" (भी अत्यधिक अनुशंसित पुस्तक) से जोड़ दूंगा: "महत्वपूर्ण: यह तंत्र केवल यह सुनिश्चित करता है कि फ़ाइल की सामग्री को छेड़छाड़ नहीं की गई है। तंत्र आपको अनुमति नहीं देता है बताएं कि प्रकाशक कौन है जब तक कि आप बिल्कुल सकारात्मक नहीं हैं कि प्रकाशक ने आपके पास सार्वजनिक कुंजी बनाई है और आप सुनिश्चित हैं कि प्रकाशक की निजी कुंजी को कभी समझौता नहीं किया गया था। " इसलिए, भले ही वे असेंबली से सार्वजनिक कुंजी को अलग-अलग प्रकाशित करते हैं, फिर भी यह आपको प्रकाशक को सत्यापित करने की अनुमति नहीं देता है। –