2012-01-15 9 views
19

मैं उपयोगकर्ता को व्यक्तिगत डेटा एन्क्रिप्टेड सहेजने की क्षमता प्रदान करना चाहता हूं। यह छोटा हो सकता है या शायद पहले से ही पूछा जा सकता है, लेकिन मैं पासवर्ड को एन्क्रिप्ट/डिक्रिप्ट करने के लिए उपयोग करने में आसान तरीका का उदाहरण नहीं ढूंढ पा रहा हूं।मैं अपने आवेदन में उपयोगकर्ता सेटिंग्स (जैसे पासवर्ड) कैसे एन्क्रिप्ट कर सकता हूं?

मुझे वास्तव में किसी सुपर-जादू-अटूट पासवर्ड की आवश्यकता नहीं है। मुझे बस तोड़ने में मुश्किल होने के लिए पासवर्ड चाहिए।

मैंने कुछ msdn और SO प्रश्नों को देखा है लेकिन उपयोग करने के लिए कुछ नहीं मिला है।

+0

संबंधित प्रश्न: [? कैसे एक डेटाबेस या पाठ फ़ाइल में बाद में इसे बचाने के लिए एक पासवर्ड एन्क्रिप्ट करने] (http://stackoverflow.com/questions/ 541,219/कैसे करने वाली एन्क्रिप्ट एक पासवर्ड के लिए बचत यह बाद में-में-एक-डेटाबेस या पाठ फ़ाइल)। और बहुत कुछ, बहुत कुछ: ['सी # एन्क्रिप्ट पासवर्ड' युक्त प्रश्न] (http://stackoverflow.com/search?q=c%23+encrypt+password)। –

+4

ध्यान दें कि जो कुछ भी आप करते हैं, आप ** * पासवर्ड * डिक्रिप्ट नहीं करते हैं **। इसके बजाय, आप सुनिश्चित करते हैं कि दो हैंश मैच। –

+1

@ कोडीग्रे एसक्यूएल कनेक्शन स्ट्रिंग में हैश पासवर्ड भेजने का कोई तरीका है? – Odys

उत्तर

31

David, मैंने सोचा your answer गंधा था, लेकिन मैंने सोचा कि उन विस्तार तरीके के रूप में niftier होगा । यही कारण है कि इस तरह के वाक्य रचना की अनुमति होगी के रूप में:

string cypherText; 
string clearText; 

using (var secureString = "Some string to encrypt".ToSecureString()) 
{ 
    cypherText = secureString.EncryptString(); 
} 

using (var secureString = cypherText.DecryptString()) 
{ 
    clearText = secureString.ToInsecureString(); 
} 

यहाँ अद्यतन कोड है:

using System; 
using System.Collections.Generic; 
using System.Runtime.InteropServices; 
using System.Security; 
using System.Security.Cryptography; 
using System.Text; 

public static class SecureIt 
{ 
    private static readonly byte[] entropy = Encoding.Unicode.GetBytes("Salt Is Not A Password"); 

    public static string EncryptString(this SecureString input) 
    { 
     if (input == null) 
     { 
      return null; 
     } 

     var encryptedData = ProtectedData.Protect(
      Encoding.Unicode.GetBytes(input.ToInsecureString()), 
      entropy, 
      DataProtectionScope.CurrentUser); 

     return Convert.ToBase64String(encryptedData); 
    } 

    public static SecureString DecryptString(this string encryptedData) 
    { 
     if (encryptedData == null) 
     { 
      return null; 
     } 

     try 
     { 
      var decryptedData = ProtectedData.Unprotect(
       Convert.FromBase64String(encryptedData), 
       entropy, 
       DataProtectionScope.CurrentUser); 

      return Encoding.Unicode.GetString(decryptedData).ToSecureString(); 
     } 
     catch 
     { 
      return new SecureString(); 
     } 
    } 

    public static SecureString ToSecureString(this IEnumerable<char> input) 
    { 
     if (input == null) 
     { 
      return null; 
     } 

     var secure = new SecureString(); 

     foreach (var c in input) 
     { 
      secure.AppendChar(c); 
     } 

     secure.MakeReadOnly(); 
     return secure; 
    } 

    public static string ToInsecureString(this SecureString input) 
    { 
     if (input == null) 
     { 
      return null; 
     } 

     var ptr = Marshal.SecureStringToBSTR(input); 

     try 
     { 
      return Marshal.PtrToStringBSTR(ptr); 
     } 
     finally 
     { 
      Marshal.ZeroFreeBSTR(ptr); 
     } 
    } 
} 
+0

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

+0

नोट को मैंने @DavidClarke के उत्तर पर नीचे दिया गया नोट देखें, और यह प्रासंगिक [msdn लिंक] देखें (https://msdn.microsoft.com/en-us/library/system.security.securestring (v = vs.110) .aspx) – Matt

16

निम्नलिखित जितना आसान हो उतना सरल है, यह मानते हुए कि आप वास्तव में केवल एक स्ट्रिंग को एन्क्रिप्ट/डिक्रिप्ट करने और डिस्क पर संग्रहीत करने में सक्षम होना चाहते हैं। ध्यान दें कि यह पासवर्ड का उपयोग नहीं करता है, यह डेटा को सुरक्षित करने के लिए लॉग इन उपयोगकर्ता System.Security.Cryptography.DataProtectionScope.CurrentUser के सुरक्षा संदर्भ का उपयोग करता है।

public class SecureIt 
{ 
    static byte[] entropy = System.Text.Encoding.Unicode.GetBytes("Salt Is Not A Password"); 

    public static string EncryptString(System.Security.SecureString input) 
    { 
     byte[] encryptedData = System.Security.Cryptography.ProtectedData.Protect(
      System.Text.Encoding.Unicode.GetBytes(ToInsecureString(input)), 
      entropy, 
      System.Security.Cryptography.DataProtectionScope.CurrentUser); 
     return Convert.ToBase64String(encryptedData); 
    } 

    public static SecureString DecryptString(string encryptedData) 
    { 
     try 
     { 
      byte[] decryptedData = System.Security.Cryptography.ProtectedData.Unprotect(
       Convert.FromBase64String(encryptedData), 
       entropy, 
       System.Security.Cryptography.DataProtectionScope.CurrentUser); 
      return ToSecureString(System.Text.Encoding.Unicode.GetString(decryptedData)); 
     } 
     catch 
     { 
      return new SecureString(); 
     } 
    } 

    public static SecureString ToSecureString(string input) 
    { 
     SecureString secure = new SecureString(); 
     foreach (char c in input) 
     { 
      secure.AppendChar(c); 
     } 
     secure.MakeReadOnly(); 
     return secure; 
    } 

    public static string ToInsecureString(SecureString input) 
    { 
     string returnValue = string.Empty; 
     IntPtr ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(input); 
     try 
     { 
      returnValue = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(ptr); 
     } 
     finally 
     { 
      System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(ptr); 
     } 
     return returnValue; 
    } 

} 

फिर एक स्ट्रिंग एन्क्रिप्ट करने के लिए:

var clearText = "Some string to encrypt"; 
    var cypherText = SecureIt.EncryptString(SecureIt.ToSecureString(clearText)); 

और बाद में डिक्रिप्ट करने के लिए:

var clearText = SecureIt.ToInsecureString(SecureIt.DecryptString(cypherText)); 
+2

यदि आप एक सुरक्षित स्ट्रिंग को डिक्रिप्ट करते हैं तो सुरक्षित स्ट्रिंग का उपयोग करने का कोई मतलब नहीं है। पूरा उद्देश्य पूर्ण स्ट्रिंग को स्मृति के एक ब्लॉक से बाहर रखना है। आप इस विधि का उपयोग करके बेहतर नहीं हैं यदि आप अभी एक स्ट्रिंग लेते हैं और इसे एन्क्रिप्ट किया जाता है: 'एक सिक्योरस्टिंग ऑब्जेक्ट स्ट्रिंग से कभी नहीं बनाया जाना चाहिए, क्योंकि संवेदनशील डेटा पहले से ही स्मृति दृढ़ता के परिणामों के अधीन है अपरिवर्तनीय स्ट्रिंग कक्षा। एक सिक्योरस्टिंग ऑब्जेक्ट बनाने का सबसे अच्छा तरीका एक चरित्र-पर-एक-बार अप्रबंधित स्रोत, जैसे कंसोल से है।ReadKey विधि। – Matt

+0

यह एक अच्छा मुद्दा है। मैं यह सुझाव नहीं दे रहा हूं कि सभी विधियों का उपयोग उसी एप्लिकेशन में किया जाना चाहिए। मैं स्ट्रिंग को कैप्चर करने के लिए एक अलग कंसोल ऐप का उपयोग कर रहा था और यूनिट टेस्ट प्रोजेक्ट की सेटिंग्स में इसे सुरक्षित रूप से संग्रहीत करने से पहले इसे एन्क्रिप्ट कर रहा था। इसका उद्देश्य उस संदर्भ के लिए पर्याप्त सुरक्षा प्रदान करना था जिसमें इसका उपयोग किया जा रहा था। –

1

मेरा उद्देश्य के लिए मैं Jesse C. Slicer समाधान SecureString का उपयोग नहीं करने के लिए संशोधित रूप में यह महत्वपूर्ण नहीं है मुझे स्मृति की रक्षा के लिए। मुझे बस एन्क्रिप्टेड तारों को क्रमबद्ध करने की आवश्यकता है। इस कार्य प्रोजेक्ट को System.Security (न केवल कथन का उपयोग करके) का संदर्भ होना चाहिए।

public static class StringSecurityHelper 
{ 
    private static readonly byte[] entropy = Encoding.Unicode.GetBytes("5ID'&mc %[email protected]%n!G^ fiVn8 *tNh3eB %rDaVijn!.c b"); 

    public static string EncryptString(this string input) 
    { 
     if (input == null) 
     { 
      return null; 
     } 

     byte[] encryptedData = ProtectedData.Protect(Encoding.Unicode.GetBytes(input), entropy, DataProtectionScope.CurrentUser); 

     return Convert.ToBase64String(encryptedData); 
    } 

    public static string DecryptString(this string encryptedData) 
    { 
     if (encryptedData == null) 
     { 
      return null; 
     } 

     try 
     { 
      byte[] decryptedData = ProtectedData.Unprotect(Convert.FromBase64String(encryptedData), entropy, DataProtectionScope.CurrentUser); 

      return Encoding.Unicode.GetString(decryptedData); 
     } 
     catch 
     { 
      return null; 
     } 
    } 
} 

और यह उपयोग करने के लिए:

string cypherText = "My string".EncryptString(); 
string clearText = cypherText.DecryptString(); 
संबंधित मुद्दे