Как безопасно сохранять имя пользователя/пароль (локально)?

Я делаю приложение Windows, которое нужно сначала войти в систему.
Детали учетной записи состоят из имени пользователя и пароля, и их необходимо сохранить локально.
Это просто вопрос безопасности, поэтому другие люди, использующие один и тот же компьютер, не могут видеть все персональные данные.
Каков наилучший/самый безопасный способ сохранить эти данные?

Я не хочу использовать базу данных, поэтому я пробовал некоторые вещи с файлами ресурсов.
Но так как я с ней немного новый, я не совсем уверен, что я делаю, и где я должен искать решение.

Ответ 1

Если вы просто проверяете/проверяете введенное имя пользователя и пароль, используйте класс Rfc2898DerivedBytes (также известный как деривация ключа на основе пароля Функция 2 или PBKDF2). Это более безопасно, чем использование шифрования, такого как Triple DES или AES, потому что нет никакого практического способа перейти от результата RFC2898DerivedBytes к паролю. Вы можете перейти только от пароля к результату. См. Можно ли использовать SHA1 хэш пароля в качестве соли при получении ключа шифрования и IV из строки пароля? для примера и обсуждения для .Net или Строка encrypt/decrypt с паролем С# Metro Style для WinRT/Metro.

Если вы сохраняете пароль для повторного использования, например, поставляя его третьему лицу, используйте API защиты данных Windows (DPAPI). Это использует сгенерированные и защищенные ключи операционной системы и алгоритм шифрования Triple DES для шифрования и дешифрования информации. Это означает, что вашему приложению не нужно беспокоиться о создании и защите ключей шифрования, что является серьезной проблемой при использовании криптографии.

В С# используйте класс System.Security.Cryptography.ProtectedData. Например, чтобы зашифровать часть данных, используйте ProtectedData.Protect():

// Data to protect. Convert a string to a byte[] using Encoding.UTF8.GetBytes().
byte[] plaintext; 

// Generate additional entropy (will be used as the Initialization vector)
byte[] entropy = new byte[20];
using(RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
    rng.GetBytes(entropy);
}

byte[] ciphertext = ProtectedData.Protect(plaintext, entropy,
    DataProtectionScope.CurrentUser);

Хранить энтропию и шифрованный текст надежно, например, в файле или разделе реестра с установленными разрешениями, чтобы только текущий пользователь мог его прочитать. Чтобы получить доступ к исходным данным, используйте ProtectedData.Unprotect():

byte[] plaintext= ProtectedData.Unprotect(ciphertext, entropy,
    DataProtectionScope.CurrentUser);

Обратите внимание, что есть дополнительные соображения безопасности. Например, избегайте хранить секреты, такие как пароли, как string. Строки неизменяемы, поскольку они не могут быть уведомлены в памяти, поэтому кто-то, смотрящий на память приложения или дамп памяти, может видеть пароль. Используйте SecureString или байт [] вместо этого и не забудьте удалить или обнулить их, как только пароль больше не понадобится.

Ответ 2

Я использовал это раньше, и я думаю, чтобы убедиться, что учетные данные сохраняются и наилучшим образом защищены

  • вы можете записать их в файл конфигурации приложения с помощью ConfigurationManager class
  • обеспечение безопасности с помощью класса SecureString
  • затем шифруя его с помощью инструментов в пространстве имен Cryptography.

Эта ссылка будет очень полезной. Я надеюсь: Нажмите здесь

Ответ 3

DPAPI только для этой цели. Используйте DPAPI для шифрования пароля при первом входе пользователя, храните его в безопасном месте (реестр пользователей, каталог данных пользовательских приложений - это некоторые варианты). Всякий раз, когда приложение запускается, проверьте местоположение, чтобы узнать, существует ли ваш ключ, если он использует DPAPI для его расшифровки и разрешения доступа, в противном случае отрицает его.