在 Windows 8 中将敏感数据保存到本地文件的最佳方式是什么?我正在开发一个需要存储 oAuth 令牌/密码的 C# 应用程序。我听说在 .NET 中加密/解密数据很常见,但我对这些机制没有任何经验。鉴于 Windows 8 应用程序有自己的类似于 Windows Phone 的个人/受保护的存储区域,是否仍然建议/需要加密?
另外,每次请求数据时加密/解密不会导致性能问题吗?(编写自定义/精简算法会更好吗?)
在 Windows 8 中将敏感数据保存到本地文件的最佳方式是什么?我正在开发一个需要存储 oAuth 令牌/密码的 C# 应用程序。我听说在 .NET 中加密/解密数据很常见,但我对这些机制没有任何经验。鉴于 Windows 8 应用程序有自己的类似于 Windows Phone 的个人/受保护的存储区域,是否仍然建议/需要加密?
另外,每次请求数据时加密/解密不会导致性能问题吗?(编写自定义/精简算法会更好吗?)
更新:请注意,虽然现代/地铁应用程序被限制互相攻击,但桌面应用程序将不受限制地访问通过这些 API 存储的所有数据。请参阅http://www.hanselman.com/blog/SavingAndRetrievingBrowserAndOtherPasswords.aspx,其中包含演示此内容的代码。
Win8 有一个名为PasswordVault的新 API ,旨在为您解决所有这些难题。非常易于使用、安全,并且可以由用户配置为在他们的机器之间漫游,因此他们只需输入一次凭据。我已成功将其用于 OAuth 令牌
检索凭据(注意 WinRT 引发的愚蠢异常......他们真的应该只返回 null):
const string VAULT_RESOURCE = "[My App] Credentials";
string UserName { get; set; };
string Password { get; set; };
var vault = new PasswordVault();
try
{
var creds = vault.FindAllByResource(VAULT_RESOURCE).FirstOrDefault();
if (creds != null)
{
UserName = creds.UserName;
Password = vault.Retrieve(VAULT_RESOURCE, UserName).Password;
}
}
catch(COMException)
{
// this exception likely means that no credentials have been stored
}
存储凭据:
vault.Add(new PasswordCredential(VAULT_RESOURCE, UserName, Password));
删除凭据(当用户单击应用程序中的注销按钮时):
vault.Remove(_vault.Retrieve(VAULT_RESOURCE, UserName));
这取决于您需要什么,如果您真的需要存储密码,您应该使用 2 路加密算法,如 3DES/RC2/Rijndael 等。
但是,如果您需要做的只是验证密码是否正确,则建议使用 oneway 函数来存储哈希。
在处理敏感数据时,我真的建议对它进行加密/散列,即使您使用 Windows 8。加密确实意味着额外的开销,但在大多数情况下,您不会注意到速度差异。
编写自己的自定义/精简算法会更好吗?作为一名安全人员,我建议不要这样做。人们花费数年时间测试、改进并试图在现有算法中找到漏洞。因此,幸存下来的人非常好。
你可以像这样加密:
public static string EncodePassword(string password)
{
byte[] bytes = Encoding.Unicode.GetBytes(password);
byte[] inArray = HashAlgorithm.Create("SHA1").ComputeHash(bytes);
return Convert.ToBase64String(inArray);
}
并且在检查用户输入时,您还将其放入此方法并检查它是否匹配。
如果您将数据放入要加密/解密的 xml(例如)中,您可以使用 RijndaelManaged。
-编辑1-
一个例子:如果你有一个弹出的小登录屏幕(ShowDialog),你可以像这样截图:
private void settings_Click(object sender, RoutedEventArgs e)
{
Login log = new Login(); //login window
log.ShowDialog(); //show the login window
string un = log.userName.Text; //the user input from the username field
string pw = log.passWord.Password; //the userinput from the password input
if (EncodePassword(un) == Properties.Settings.Default.adminUsername && EncodePassword(pw) == Properties.Settings.Default.adminPassword) //in my case, i stored it in the app settings, but this could also be somewhere else.
{
//login was correct
//do something
}
else
{
//login was not correct
}
}