对于C#控制台应用程序,我需要在应用程序设置中保留密码,但是当我创建类型为System.Security.SecureString
的设置时,设置本身将从纯文本配置文件中删除。由于我无法再看到原始值,因此无法验证数据在保存时是否仍然是加密的。
SecureString
是最佳方法,还是应该使用ProtectedData
来简单加密字符串?
- EDIT--
以下是我用来验证SecureString
可以保留的测试代码。
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public global::System.Security.SecureString Password
{
get
{
return ((global::System.Security.SecureString)(this["Password"]));
}
set { this["Password"] = value; }
}
static void Main(string[] args)
{
PersistPassword("A-Test-Password");
Console.WriteLine(ReadPassword());
Console.ReadLine();
}
static void PersistPassword(string Password)
{
SecureString ss = new SecureString();
Password.ToCharArray().ToList().ForEach(ss.AppendChar);
Settings.Default.Password = ss;
}
static string ReadPassword()
{
SecureString ss = Settings.Default.Password;
IntPtr ptr = Marshal.SecureStringToCoTaskMemUnicode(ss);
return Marshal.PtrToStringUni(ptr);
}
答案 0 :(得分:1)
作为MSDN中的州,
在初始化实例或修改值时,使用底层平台支持的机制自动保护SecureString实例的值。
如果您希望提供一种机制,只要在securestring中存储密码,就可以将其保密,然后就可以在其上调用方法MarkAsReadonly()
。
出于持久性目的,您还可以散列SecureString
并为其创建一个盐。您可以检索盐以供以后使用,例如比较pupose。查看Securestring
上使用盐的this代码段。
答案 1 :(得分:1)
您不能保留使用 SecureString 加密的数据。密钥保存在内存中,并且仅在程序运行时才存在。 SecureString是原生CryptProtectMemory函数的包装。
如果需要加密的数据以可持久化(比程序存在的时间更长),则需要数据保护API (DPAPI),它是CryptProtectData函数-通过 ProtectedData 类向C#用户公开。
SecureString 具有短暂的优势;对以下有用:
在您的程序正在使用它们时-然后将其删除。
DPAPI更适合长期存储。但是要当心保护级别,然后选择适合您需要的保护级别:
如果您需要能够在传输到不同站点或不同域的传输过程中幸免的加密:CryptProtectData不适合您。