C# - безопасное хранение пароля локально

Я создаю приложение c#, которое будет блокировать функциональность (комбинации клавиш, панель задач windows и т. д.) в киоске стиле. Одним из требований является то, что некоторые люди все равно должны иметь возможность вырваться из приложения, используя комбинацию клавиш и пароль.

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

6 ответов


стандартный метод хранения пароля в конфигурационном файле заключается в использовании сильного хэш-алгоритма. Прочитайте ответ на Как хранить пароли в приложении Winforms? и, возможно, статья wiki в https://en.wikipedia.org/wiki/Cryptographic_hash_function


сохранить безопасную хэш пароля, он не должен быть обратимым.

когда кто-то вводит пароль, хэш, что один и тот же алгоритм и проверить его хеш.

потому что вы никогда не храните пароль, это безопасно.

Я рекомендую использовать алгоритм растяжения ключа, такой как PBKDF2. .Net поддерживает это с помощью Rfc2898DeriveBytes или вы можете использовать System.Web.Helpers.Crypto.


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


Я не согласен с Брайаном, потому что на данный момент стандартным методом хранения паролей в любой базе данных является " соль "(см. Википедия для подробного объяснения) пароль со случайно сгенерированным значением и хранить хэшированное значение и соль в вашей" базе данных " (см. Примечания). Соль не секрет, поэтому вы можете хранить ее в виде обычного текста. Всякий раз, когда пользователь вводит пароль, Вы читаете соль из своего файла, применяете его к введенному паролю, а затем применяете свой выбранный алгоритм хэширования. Затем вы сравниваете результаты с сохраненным хэшем. Если они совпадают, пользователь аутентифицируется. Для хорошего (и занимательного :)) объяснения, почему "просто" хэширования пароля недостаточно, см.: как не хранить пароли! Для реализации учебного процесса соления и хэширования в C# см.:C# Соление И Хэширование Паролей

вы также можете найти хороший способ, чтобы сделать это здесь: https://stackoverflow.com/a/12657970


Для краткой справки, процесс в псевдокоде:

первое хранение пароля:

//get user input
username = GetUserName
password = GetPassword

//generate random salt
salt = GetRandomValue

//combine password and salt and apply hash
hashedPassword = Hash(password + salt)

//store hash value and salt in database
AddToDatabase(username, hashedPassword, salt)


логин:

//get user input
username = GetUserName
password = GetPassword

//read salt from database
salt = GetSaltFromDatabase(username)

//combine password and salt and apply hash
hashedPassword = Hash(password + salt)

//compare hash to stored hash value
correctHash = GetHashFromDatabase(username)
if (hashedPassword == correctHash) then
    passwordIsCorrect = True
else
    passwordIsCorrect = False
end if


Примечания:

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

вам нужен хэш пароля и проверка с использованием хэшированного текста. Добавление соли может сделать ваш пароль более безопасным. В .Net, вы можете использовать


относительно легко использовать ProtectSection() и UnprotectSection() методы SectionInformation класса. См. эту статью:

http://www.davidgiard.com/2012/06/05/EncryptingAndDecryptingApplicationConfigSections.aspx

http://msdn.microsoft.com/en-us/library/system.configuration.sectioninformation.protectsection.aspx