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

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

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


person romatthe    schedule 06.06.2013    source источник
comment
Как насчет настройки локальной учетной записи администратора вместо DIY? В любом случае ваше приложение не будет блокировать Ctrl + Alt + Del.   -  person Henk Holterman    schedule 06.06.2013
comment
Нет, не будет. Но требуется, чтобы у человека был полный доступ к текущему сеансу. К сожалению, я не могу этого изменить.   -  person romatthe    schedule 06.06.2013


Ответы (6)


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

person Brian O''Byrne    schedule 06.06.2013
comment
Обратите внимание: вы всегда должны солить свои пароли перед хешированием, чтобы избежать радужные атаки! - person Marcus Mangelsdorf; 02.02.2016

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

Когда кто-то вводит пароль, вы хешируете его по тому же алгоритму и проверяете, соответствует ли он хешу.

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

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

person Keith    schedule 06.06.2013

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

person rpeshkov    schedule 06.06.2013

Я должен не согласиться с Брайаном, потому что на данный момент стандартным методом хранения паролей в любой базе данных является «соль» (см. Википедия для подробного объяснения) пароль со случайно сгенерированным значением и сохраните хешированное значение и соль в своей «базе данных» (см. примечания) . Соль не является секретом, поэтому вы можете хранить ее в виде обычного текста. Каждый раз, когда пользователь вводит пароль, вы читаете соль из своего файла, применяете ее к введенному паролю, а затем применяете выбранный вами алгоритм хеширования. Затем вы сравниваете результаты с сохраненным хешем. Если они совпадают, пользователь аутентифицируется. Хорошее (и занимательное :)) объяснение того, почему «просто» хеширования пароля недостаточно, см .: Как НЕ хранить пароли! Учебное пособие по реализации процесса соления и хеширования на C # см .: C # Salting & Hashing Passwords

Вы также можете найти хороший способ сделать это здесь: 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


Примечания:

  • Это предполагает, что ваши имена пользователей уникальны, поскольку они используются в качестве ключа идентификации в вашей «базе данных».
  • «База данных» не обязательно должна быть какой-либо «реальной» базой данных, это также может быть ваш файл конфигурации или простой текстовый файл.
person Marcus Mangelsdorf    schedule 05.01.2015

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

Здесь хорошая статья о том, как хранить ваши пароли, и я использую ее в своем веб-приложении. .

person Chris Li    schedule 06.06.2013

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

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

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

person Oscar    schedule 06.06.2013
comment
Хорошая ссылка, но ответы не должны быть просто ссылкой и не более того. - person Keith; 06.06.2013
comment
Есть полная статья, намного лучше, чем любое краткое объяснение, которое я могу дать здесь ;-) - person Oscar; 06.06.2013
comment
возможно, но со временем ссылки отмирают. Обязательно дайте ссылку на более длинную статью, но ответ должен быть полным, если эта ссылка изменится. - person Keith; 06.06.2013