Лучшие практики для сохранения конфиденциальных данных в Windows 8 - PullRequest
29 голосов
/ 29 января 2012

Каков наилучший способ сохранения конфиденциальных данных в локальном файле в Windows 8?Я занимаюсь разработкой приложения на C #, которое должно хранить oAuth-токены / пароли.Я слышал, что в .NET было обычным делом шифровать / дешифровать данные, но у меня нет никакого опыта работы с этой механикой.Шифрование все еще рекомендуется / необходимо, учитывая, что приложения Windows 8 имеют свою собственную личную / защищенную область хранения, аналогичную Windows Phone?

Кроме того, не шифрование / дешифрование каждый раз, когда вы запрашиваете данные, вызывает проблемы производительности?(было бы лучше написать собственный / облегченный алгоритм?)

Ответы [ 3 ]

48 голосов
/ 29 января 2012

ОБНОВЛЕНИЕ: Имейте в виду, что, хотя современные / метро приложения не могут соваться друг с другом, настольные приложения будут иметь неограниченный доступ ко всем данным, хранящимся через эти API. См. http://www.hanselman.com/blog/SavingAndRetrievingBrowserAndOtherPasswords.aspx, который включает код, демонстрирующий это.


В Win8 появился новый API под названием PasswordVault , предназначенный для решения всех этих сложных проблем. Действительно прост в использовании, безопасен и может быть настроен пользователями на роуминг между своими компьютерами, поэтому им нужно вводить учетные данные только один раз. Я успешно использовал это для токенов OAuth

Получение учетных данных (обратите внимание на глупое исключение, которое вызывает WinRT ... они действительно должны просто возвращать ноль):

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));
0 голосов
/ 29 января 2012

Это зависит от того, что вам нужно, если вам действительно нужно хранить пароли, вы должны использовать двухсторонний алгоритм шифрования, такой как 3DES / RC2 / Rijndael и т. Д.Для проверки правильности пароля рекомендуется использовать одностороннюю функцию для хранения хэша.

При работе с конфиденциальными данными я действительно рекомендую шифровать / хэшировать их, даже если вы используете Windows 8. Шифрование означает дополнительные затраты, но в большинстве случаев вы не заметите разницу в скорости.Было бы лучше написать свой собственный алгоритм Custom / Lite?Как охранник я советую против этого.Люди проводят годы, тестируя, совершенствуясь и пытаясь найти дыры в существующих алгоритмах.Поэтому те, которые выжили, довольно хороши.

0 голосов
/ 29 января 2012

вы можете зашифровать так:

    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
    }
}
...