संक्षिप्त जवाब
मैं अभी क्यों नहीं कह सकता:
SecureString password = new SecureString("password");
क्योंकि अब तुम्हारी password
याद में है; इसे पोंछने का कोई तरीका नहीं है - जो कि बिल्कुल सिक्योरस्ट्रिंग की बात है ।
लंबा जवाब
SecureString मौजूद है इसका कारण यह है कि जब आप इसके साथ संवेदनशील डेटा को पोंछने के लिए ZeroMemory का उपयोग नहीं कर सकते हैं। यह CLR के कारण मौजूद किसी समस्या को हल करने के लिए मौजूद है ।
एक नियमित देशी एप्लिकेशन में आप कॉल करेंगे SecureZeroMemory
:
शून्य के साथ स्मृति का एक ब्लॉक भरता है।
नोट : SecureZeroMemory समान है ZeroMemory
, सिवाय इसके कि कंपाइलर इसे ऑप्टिमाइज़ नहीं करेगा।
समस्या यह है कि आप .NET को कॉल या अंदर नहीं कर सकते । और .NET स्ट्रिंग्स में अपरिवर्तनीय हैं; आप स्ट्रिंग की सामग्री को भी नहीं लिख सकते हैं जैसे आप अन्य भाषाओं में कर सकते हैं:ZeroMemory
SecureZeroMemory
//Wipe out the password
for (int i=0; i<password.Length; i++)
password[i] = \0;
तो आप क्या कर सकते हैं? जब हम इसके साथ काम करते हैं तो हम पासवर्ड से या पासवर्ड से क्रेडिट कार्ड नंबर को मिटा देने की .NET में क्षमता कैसे प्रदान करते हैं?
एकमात्र तरीका यह किया जा सकता है कि स्ट्रिंग को कुछ देशी मेमोरी ब्लॉक में रखें, जहां आप फिर कॉल कर सकते हैं ZeroMemory
। एक देशी मेमोरी ऑब्जेक्ट जैसे:
- एक बीटीएस
- एक HGLOBAL
- CoTaskMem अप्रबंधित स्मृति
सिक्योरस्ट्रिंग खोई हुई क्षमता को वापस देता है
.NET में, स्ट्रिंग्स को मिटाया नहीं जा सकता है जब आप उनके साथ होते हैं:
- वे अपरिवर्तनीय हैं; आप उनकी सामग्री को अधिलेखित नहीं कर सकते
- आप
Dispose
उनमें से नहीं कर सकते
- उनकी सफाई कूड़ा उठाने वाले की दया पर है
SecureString स्ट्रिंग्स सुरक्षा के चारों ओर से गुजरने के एक रास्ते के रूप में मौजूद है, और जब आपको आवश्यकता होती है तो उनकी सफाई की गारंटी देने में सक्षम हो।
आपने प्रश्न पूछा:
मैं अभी क्यों नहीं कह सकता:
SecureString password = new SecureString("password");
क्योंकि अब तुम्हारी password
याद में है; इसे पोंछने का कोई तरीका नहीं है। यह तब तक वहीं अटका रहता है जब तक कि सीएलआर उस मेमोरी को फिर से इस्तेमाल करने का फैसला नहीं करता। आपने हमें वापस वहीं रखा है जहाँ हमने शुरू किया था; एक पासवर्ड के साथ एक रनिंग एप्लिकेशन जिससे हम छुटकारा नहीं पा सकते हैं, और जहां एक मेमोरी डंप (या प्रोसेस मॉनिटर) पासवर्ड देख सकते हैं।
SecureString मेमोरी में एन्क्रिप्टेड स्ट्रिंग को स्टोर करने के लिए डेटा प्रोटेक्शन एपीआई का उपयोग करता है; इस तरह से स्ट्रिंग swapfiles, क्रैश डंप, या यहां तक कि स्थानीय चर विंडो में किसी सहकर्मी के साथ आपकी इच्छा से मौजूद नहीं होगी।
मैं पासवर्ड कैसे पढ़ूं?
फिर सवाल है: मैं स्ट्रिंग के साथ कैसे बातचीत करूं? आप बिल्कुल ऐसा तरीका नहीं चाहते हैं:
String connectionString = secureConnectionString.ToString()
क्योंकि अब आप वापस वहीं हैं जहाँ आपने शुरू किया था - एक पासवर्ड जिससे आप छुटकारा नहीं पा सकते। आप डेवलपर्स को संवेदनशील स्ट्रिंग को सही ढंग से संभालने के लिए मजबूर करना चाहते हैं - ताकि इसे मेमोरी से मिटा दिया जा सके।
यही कारण है कि .NET एक सुरक्षित स्मृति में एक SecureString को सुरक्षित करने के लिए तीन आसान सहायक कार्य प्रदान करता है:
आप स्ट्रिंग को एक अप्रबंधित मेमोरी ब्लॉब में परिवर्तित करते हैं, इसे संभालते हैं, और फिर इसे फिर से पोंछते हैं।
कुछ एपीआई सिक्योरस्ट्रीम को स्वीकार करते हैं । उदाहरण के लिए ADO.net 4.5 में SqlConnection.Credential एक सेट SqlCredential लेता है :
SqlCredential cred = new SqlCredential(userid, password); //password is SecureString
SqlConnection conn = new SqlConnection(connectionString);
conn.Credential = cred;
conn.Open();
आप कनेक्शन स्ट्रिंग के भीतर पासवर्ड भी बदल सकते हैं:
SqlConnection.ChangePassword(connectionString, cred, newPassword);
और .NET के अंदर बहुत सारे स्थान हैं जहां वे संगतता उद्देश्यों के लिए एक सादे स्ट्रिंग को स्वीकार करना जारी रखते हैं, फिर जल्दी से एक पुट के चारों ओर इसे एक SecureString में बदल देते हैं।
सिक्योरस्ट्रिंग में टेक्स्ट कैसे डालें?
यह अभी भी समस्या छोड़ देता है:
मैं पहली बार SecureString में एक पासवर्ड कैसे प्राप्त करूं?
यह चुनौती है, लेकिन बात आपको सुरक्षा के बारे में सोचने की है।
कभी-कभी आपके लिए कार्यक्षमता पहले से ही प्रदान की जाती है। उदाहरण के लिए, WPF PasswordBox नियंत्रण आप एक के रूप में दर्ज पासवर्ड लौट सकते हैं SecureString सीधे:
वर्तमान में PasswordBox द्वारा सुरक्षित पासवर्ड के रूप में रखे गए पासवर्ड को प्राप्त करता है ।
यह मददगार है क्योंकि हर जगह जब आप एक कच्ची स्ट्रिंग के आसपास से गुजरते थे, तो अब आपके पास यह टाइप करने की प्रणाली है कि सिक्योरस्ट्रिंग स्ट्रिंग से असंगत है। आप अपने सिक्योरस्ट्रीमिंग को नियमित स्ट्रिंग में परिवर्तित करने से पहले जितना संभव हो उतना लंबा चलना चाहते हैं।
एक SecureString परिवर्तित करना काफी आसान है:
- SecureStringToBSTR
- PtrToStringBSTR
जैसे की:
private static string CreateString(SecureString secureString)
{
IntPtr intPtr = IntPtr.Zero;
if (secureString == null || secureString.Length == 0)
{
return string.Empty;
}
string result;
try
{
intPtr = Marshal.SecureStringToBSTR(secureString);
result = Marshal.PtrToStringBSTR(intPtr);
}
finally
{
if (intPtr != IntPtr.Zero)
{
Marshal.ZeroFreeBSTR(intPtr);
}
}
return result;
}
वे वास्तव में आप ऐसा नहीं करना चाहते हैं।
लेकिन मैं सिक्योरस्ट्रिंग में स्ट्रिंग कैसे प्राप्त करूं? वैसे आपको जो करने की आवश्यकता है वह पहली जगह में एक स्ट्रिंग में एक पासवर्ड होना बंद कर देता है। आपको इसे किसी और चीज़ में रखने की ज़रूरत है । भले हीChar[]
सरणी भी सहायक होगी।
जब आप प्रत्येक वर्ण को जोड़ सकते हैं और जब आप पूरा कर लेते हैं तो सादे को मिटा सकते हैं:
for (int i=0; i < PasswordArray.Length; i++)
{
password.AppendChar(PasswordArray[i]);
PasswordArray[i] = (Char)0;
}
आपको अपना पासवर्ड कुछ मेमोरी में संग्रहीत करना होगा जिसे आप मिटा सकते हैं। इसे वहां से SecureString में लोड करें।
tl; डॉ: SecureString के बराबर प्रदान करने के लिए मौजूद है ZeroMemory ।
कुछ लोग डिवाइस के लॉक होने पर उपयोगकर्ता के पासवर्ड को मेमोरी से पोंछने की स्थिति में नहीं दिखते हैं , या फिर वेहुथेंटेड के बाद मेमोरी से कीस्ट्रोक्स को पोंछते हुए । वे लोग SecureString का उपयोग नहीं करते हैं।
SecureString
नए विकास के लिए अनुशंसा नहीं करते हैं : github.com/dotnet/platform-compat/blob/master/docs/DE0001.md