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