在Windows 8中保存敏感数据的最佳实践

时间:2012-01-29 10:29:39

标签: c# windows-8 windows-runtime passwordvault

将敏感数据保存到Windows 8中的本地文件的最佳方法是什么?我正在开发一个需要存储oAuth令牌/密码的C#应用​​程序。我听说在.NET中加密/解密数据很常见,但我对这些机制没有任何经验。鉴于Windows 8应用程序有自己的个人/受保护存储区域类似于Windows Phone,是否仍建议使用加密?

此外,每次请求数据时都不会加密/解密导致性能问题? (编写自定义/精简算法会更好吗?)

3 个答案:

答案 0 :(得分:48)

更新请注意,虽然现代/都市应用程序不会互相攻击,但桌面应用程序可以无限制地访问通过这些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));

答案 1 :(得分:0)

这取决于你需要什么,如果你真的需要存储密码,你应该使用双向加密算法,如3DES / RC2 / Rijndael等。

但是,如果您只需要验证密码是否正确,建议使用单向函数来存储哈希值。

在处理敏感数据时,我真的建议使用加密/哈希,即使你使用的是Windows 8.加密确实意味着额外的开销,但在大多数情况下你不会注意速度差异。

编写自己的自定义/ lite算法会更好吗?作为安全人员,我建议不要这样做。人们花费数年时间测试,改进并试图在现有算法中找到漏洞。幸存下来的人非常好。

答案 2 :(得分:-4)

你可以像这样加密:

    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。

-Edit1 -

一个例子: 如果你有一个弹出的小登录界面(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
    }
}