如何在我的应用程序中加密用户设置(如密码)?

我想为用户提供保存加密的个人数据的能力。 这可能是微不足道的,或者可能已经被问过,但我无法找到一个易于使用的方法来加密/解密密码的示例。

我真的不需要任何超级魔法 – 牢不可破的密码。 我只需要密码就像难以破解一样。

我已经看到一些msdn和SO问题,但没有找到一些东西可以使用。

大卫 ,我认为你的答案很漂亮,但我认为那些作为扩展方法会更加狡猾。 这将允许这样的语法:

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 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); } } } 

以下是一样简单,假设您真的只想加密/解密字符串并将其存储到磁盘。 请注意,这不使用密码,它使用登录用户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)); 

为了我的目的,我修改了Jesse C. Slicer解决方案,不使用SecureString因为保护内存对我来说并不重要。 我只需要序列化加密的字符串。 要使这个工作项目需要引用System.Security (不仅仅是使用语句)。

 public static class StringSecurityHelper { private static readonly byte[] entropy = Encoding.Unicode.GetBytes("5ID'&mc %sJo@lGtbi%n!G^ fiVn8 *tNh3eB %rDaVijn!.cb"); 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();