2008-09-29 8 views
7

सुविधा अनुरोधों मैं इस कार्यक्रम मैं पर काम कर रहा हूँ के लिए मिल गया है में से एक सहेजा जा रहा है क्रेडेंशियल्स उपयोगकर्ताओं में प्रवेश की सूची को बचाने के लिए सक्षम होने के लिए है, तो वे चारों ओर से साझा किया जा सकता है। इस अनुरोध को प्रेरित करने वाले विशिष्ट उपयोग मामले में हमारे कार्यक्रम का उपयोग बड़े कॉर्पोरेट नेटवर्क पर किया जा रहा था, जो एक फ्लैकी वैन से जुड़े काफी अच्छे LAN से बना था। विचार यह था कि, जब हमारे डाउन होने पर WAN के खिलाफ हमारे प्रोग्राम को हराया जाता है, तो वे एक 'कॉन्फ़िगरेशन' फ़ाइल भेजते हैं जिसमें बारीकी से संरक्षित व्यवस्थापक क्रेडेंशियल्स होते हैं, इसे प्रत्येक लैन में चलाएं और परिणाम को ज़िप करें और इसे ई-मेल करें वापस।एक SecureString

हाँ।

मेरा प्रारंभिक वृत्ति इस अनुरोध पर रोक लगाने के लिए है - पासवर्ड सहेजना? वास्तव में? और निश्चित रूप से कंपनी का नेटवर्क डिवीजन आपको वांछित उत्पादों के किसी भी उत्पाद को बेचने और बेचने के लिए पसंद करेगा - लेकिन यह उन वर्गों में से एक है जो मैं प्रमाण पत्र का उपयोग करता हूं, एक सिक्योरस्ट्रिंग ले सकता है, और, ठीक है, यह देखना हमेशा अच्छा होता है तरीकों से आप लोगों को कुछ प्रयास बचा सकते हैं। यही कारण है कि मुझे सोच को मिला:

यह इतना है कि मैं एक फाइल करने के लिए संवेदनशील डेटा को बचाने और इसे किसी और किसी ऐसे स्थान पर खोल सकते हैं, एक एन्क्रिप्टेड SecureString को बचाने के लिए संभव है?

आपके विचार क्या हैं, स्टैक ओवरफ़्लो?

+0

आपका मतलब है "नेटवर्क विफलता के मामले में साझा किया गया"? क्या आप उस पर विस्तार कर सकते हैं? –

उत्तर

5

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

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

यह सब एक तरफ, मेरस, मैं सुझाव दूंगा कि आप समग्र प्रणाली में सुधार करने का प्रयास करें क्योंकि उपयोग के मामले में आप वर्णन कर रहे हैं (माना जाता है कि मैं इसे समझता हूं) आप बेहतर हैश की तुलना में बेहतर है वास्तविक पासवर्ड

+1

मैं उम्मीद कर रहा था कि सिक्योरस्ट्रिंग मेरे लिए हैश करेगी। मैं अपने स्वयं के हैशिंग फ़ंक्शन को रोल करने से बेहतर जानता हूं। – Merus

+1

पावरहेल में सिक्योरस्ट्रिंग को बचाया जा सकता है, किसी भी तरह से सी # ?? http://stackoverflow.com/questions/11174425/how-does-one-securely-handle-passwords-in-a-custom-written-powershell-cmdlet – Kiquenet

3

आप SecureString के एन्क्रिप्टेड बाइट्स बचत मतलब तो यह काम नहीं करेगा - SecureString के लिए महत्वपूर्ण उपयोगकर्ता और इस प्रक्रिया से जुड़ा हुआ है। एक अलग प्रक्रिया में या किसी भिन्न उपयोगकर्ता के लिए उन बाइट्स में पढ़ें, और स्ट्रिंग को डिक्रिप्ट करने का कोई तरीका नहीं है।

1

आप IsolatedStorageFileStream class पर एक नज़र डालें कर सकते हैं। यह फ़ाइल डेटा लिखने और स्टोर करने के तरीके निर्दिष्ट करता है जिसे केवल आपकी असेंबली द्वारा एक्सेस किया जा सकता है।

मुझे नहीं लगता कि आप इस पर SecureString का उपयोग कर सकते हैं।

1

SecureString serializable ताकि आप न सिर्फ जन्म दिया serializers (बाइनरी, एक्सएमएल, आदि)

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

3

यह एक सिक्योरस्ट्रिंग के बिंदु को हरा देगा, जो स्मृति में रहने की गारंटी है। इसलिए यदि आप इसे फ़ाइल में सहेज रहे हैं, तो आप इसे सामान्य स्ट्रिंग के रूप में भी सहेज सकते हैं, क्योंकि यह अब "सुरक्षित" नहीं है।

4

आप पासवर्ड हैश की तुलना करना चाहेंगे।
आपके पास उपयोगकर्ता नाम से नमक होगा और शायद कुछ अन्य निरंतर, स्ट्रिंग के बाद। फिर, आप इसे हैशिंग एल्गोरिदम में भेज देंगे, जैसे SHA1 *।
उदाहरण के लिए,

using System.Security.Cryptography; 

public byte[] GetPasswordHash(string username, string password, string salt) 
{ 
    // get salted byte[] buffer, containing username, password and some (constant) salt 
    byte[] buffer; 
    using (MemoryStream stream = new MemoryStream()) 
    using (StreamWriter writer = new StreamWriter(stream)) 
    { 
     writer.Write(salt); 
     writer.Write(username); 
     writer.Write(password); 
     writer.Flush(); 

     buffer = stream.ToArray(); 
    } 

    // create a hash 
    SHA1 sha1 = SHA1.Create(); 
    return sha1.ComputeHash(buffer); 
} 

उसके बाद, आप GetPasswordHash(username, givenPassword, salt) करने के लिए GetPasswordHash(username, expectedPassword, salt) के लिए परिणाम की तुलना करेंगे।
यदि आप उपयोगकर्ता नाम और पासवर्ड के साथ अपनी खुद की उपयोगकर्ता सूची लागू करते हैं, तो आप केवल हैश (GetPasswordHash(username, givenPassword, salt)) को सहेजने और सहेजे गए हैश के विरुद्ध तुलना करने पर विचार कर सकते हैं।

+0

कभी-कभी दिए गए पासवर्ड की तुलना करना कार्य नहीं है लेकिन प्रोग्राम स्वयं ही चाहता है अन्य सिस्टम में प्रमाणीकरण प्राप्त करने के लिए पासवर्ड का उपयोग करने के लिए। मेल क्लाइंट की तरह एसएमटीपी सर्वर में प्राधिकरण प्राप्त करने के लिए पासवर्ड का उपयोग करें। हम उस स्थिति में क्या कर सकते हैं –

+0

@ शंकरन: प्रत्येक मामले का अपना समाधान होता है। अधिकांश आधुनिक एपीआई पहले ही पासवर्ड हैश स्वीकार करते हैं; कुछ में एपीआई कुंजी हैं इसलिए आपको पासवर्ड के हैश को जानने की भी आवश्यकता नहीं है। पुरानी एपीआई का उपयोग करने के लिए जो केवल पासवर्ड का उपयोग करने का समर्थन करता है, आपके पास पासवर्ड को स्टोर करने के अलावा कोई विकल्प नहीं होगा। उस स्थिति में, मैं कुछ प्रकार की एन्क्रिप्शन का उपयोग करता हूं, हालांकि यह बहुत अधिक व्यर्थ है। – configurator

+0

MD5 हैश एल्गोरिदम विकल्प के रूप में पूरी तरह से अनुचित है। आपको bcrypt या scrypt, या _least_ sha1 (और यहां तक ​​कि वास्तव में अनुशंसित नहीं है) की आवश्यकता है। –

0

जैसा कि यहां बताया गया है, SecureString इस परिदृश्य में उपयोग करने का सबसे अच्छा तरीका नहीं है।

अगर मैं साझा करने के लिए की जरूरत थी उपयोगकर्ताओं साख मैं शायद उपयोगकर्ता नाम नमकीन पासवर्ड साझा करेंगे और टुकड़ों में बांटा + है, तो आप सुरक्षित हो सकता है और केवल एक पासवर्ड की प्रतिनिधित्व साझा करते हैं, नहीं यह सामग्री है।

बस इस के लिए रास्ता उदाहरण के लिए BCryt लाइब्रेरी (where there's a .NET representation of it) का उपयोग किया जाता है और केवल एक तालिका में उपयोगकर्ता नाम और पासवर्ड प्रतिनिधित्व तैयार साझा करने के लिए

इस तरह आप इसका इस्तेमाल होता है की मेजबानी:

StringBuilder sb = new StringBuilder(); 

// run ADO.NET/Entity Framework/etc and query your DB with something like: 
"SELECT user_id, username, password FROM [TblUsers];" 

// loop through the results 

sb.AppendFormat(
     "INSERT INTO [TblSharedUsers] SELECT '{0}','{1}','{2}'",    
      dr["id"], dr["username"], 
      BCrypt.HashPassword(dr["password"], BCrypt.GenerateSalt(12)); 
     ); 

// then run sb.ToSTring() agains your db 
ग्राहक अंत पर

, आप बना सकते हैं एक नया AuthenticationProviderTblSharedUsers से पढ़ता है कि और उपयोगकर्ता पासवर्ड की जांच (इसलिए यह जब नेटवर्क IoC और DI का उपयोग कर उपलब्ध नहीं है बदलने के लिए आसान हो जाएगा)

string userPassword = Request["password"]; 

"SELECT id, password FROM [TblSharedUsers] WHERE username = @usr;" 

if(BCrypt.CheckPassword(userPassword, dr["password"])) 
    // User can log in 
else 
    // Credentials are invalid 

मुझे आशा है कि यह किसी को भी एक ही समस्या के साथ मदद करेगा।

संबंधित मुद्दे

 संबंधित मुद्दे