Где хранить пароли БД при использовании приложений Windows .NET или ASP.NET
У меня есть сценарий, который беспокоил меня в течение многих лет. Если вам необходимо подключиться к базе данных или другому сервису (например, веб-сервису), используя имя пользователя и пароль, где было бы безопаснее всего хранить эту информацию, если вы подключаетесь через сборку.NET? Я понимаю, что вам придется зашифровать пароль, но затем вы столкнетесь с проблемой куриного яйца - хорошо - вы можете зашифровать ее, но тогда где вы положите ключ?
В.NET вы не можете жестко закодировать пароль, потому что вы можете декомпилировать код.NET.
Я рассмотрел использование прав на основе сборок в изолированном хранилище, но MS рекомендует не хранить там незашифрованные секретные элементы, потому что привилегированные пользователи могут получить доступ, поэтому мы снова переносим проблему из точки А в точку Б. Так, например, администратор домена с нет необходимости знать об информации в базе данных, чтобы иметь возможность получить доступ из-за способности быть администратором на любой рабочей станции в домене.
Вы можете зашифровать App.Config и Web.Config, но я считаю, что пользователи привилегий могут получить доступ к ключам.
Я думаю, что вы столкнулись с той же проблемой с DPAPI.
Я подумывал о том, чтобы хранить пароли, зашифрованные в удаленной базе данных и получать их через аутентификацию ОС, но наш отдел запрещает хранение паролей на серверах баз данных. Я почти уверен, что застрял и хотел подтверждения.
4 ответа
Вы не хотите хранить пароль в сборке, и повторное изобретение колеса только создает больше проблем (и создает больше уязвимостей), чем оно того стоит. Если вы используете платформу MS как на базе данных, так и на веб-сервере, то самый простой способ справиться с этим - использовать доверенное соединение и предоставить права на SQL-сервере идентификатору, используемому вашим приложением.
Во-вторых, я бы просто позволил DPAPI выполнять свою работу по шифрованию настроек вашего соединения.
Вы можете использовать следующие методы .NET Framework для защиты ваших данных, они используют DPAPI для внутренней защиты ваших данных, и вы можете напрямую использовать их в C# или VB.NET без необходимости возиться с системными вызовами DLL:
namespace System.Security.Cryptography
{
// Summary:
// Provides methods for protecting and unprotecting data. This class cannot
// be inherited.
public sealed class ProtectedData
{
public static byte[] Protect(byte[] userData,
byte[] optionalEntropy, DataProtectionScope scope);
public static byte[] Unprotect(byte[] encryptedData,
byte[] optionalEntropy, DataProtectionScope scope);
}
}
Чтобы использовать его, добавьте ссылку System.Security
к вашему проекту. Я настоятельно рекомендую использовать байтовый массив optionalEntropy
добавить SALT к вашим защищенным данным (добавить несколько случайных значений в байтовый массив, которые являются уникальными для данных, которые вы собираетесь защищать).
За scope
ты можешь использовать DataProtectionScope.CurrentUser
, который будет шифровать данные для защиты с учетными данными текущего пользователя.
В некоторых сценариях DataProtectionScope.LocalMachine
также полезно. В этом случае защищенные данные связаны с контекстом компьютера. С этой настройкой любой процесс, запущенный на компьютере, может снять защиту данных. Обычно он используется в серверных приложениях, которые работают на сервере, где недоверенным пользователям запрещен доступ.
Использовать Protect
метод для шифрования данных, расшифровать его с помощью Unprotect
, Вы можете хранить возвращенный байтовый массив в соответствии с требованиями вашего приложения (файл, база данных, реестр и т. Д.).
Подробнее об этих методах можно узнать здесь, на MSDN:
- Защита данных Windows - общая информация о функциональности DPAPI,
- Защищенный класс данных - спецификация
ProtectedData
учебный класс, - Защитный метод - описание использования
Protect
метод
Для примеров кода и в случае, если вы заинтересованы в шифровании частей файла.config приложений, проверьте это:
- Шифрование паролей в config - статья, которая объясняет, как шифровать части web/app.config
Я рекомендую вам использовать соль (то есть, используя optionalEntropy
параметр) - защищает от атак на радужные таблицы.
Я хотел бы упомянуть один недостаток решения DPAPI: ключ генерируется на основе ваших учетных данных Windows, что означает, что тот, кто имеет доступ к вашим учетным данным Windows, может иметь доступ к защищенным данным. Программа, работающая под вашей учетной записью, также может получить доступ к защищенным данным.
Это хороший вопрос, и я сам искал ответ. У меня была проблема с безопасностью паролей БД на случай взлома сервера и получения отдельных файлов. Одна очень интересная опция, которую я нашел, заключалась в том, что разделы web.config могут быть зашифрованы и расшифрованы автоматически на лету.NET Framework, который будет использовать безопасное хранилище Windows для хранения и получения ключа шифрования для вас. В моей ситуации это было недоступно, потому что мой хостинг-провайдер не поддерживал его, но вы можете посмотреть на эту опцию. Я думаю, что это может сработать, потому что вы можете самостоятельно управлять безопасностью пользователей, которые могут получить доступ к безопасному хранилищу Windows, и значительно ограничивать любые потенциальные нарушения. Хакер, взломавший сервер, может получить копию ваших файлов конфигурации и всех ваших сборок, но доступ к ключу расшифровки будет для него еще одним препятствием.
Если вы используете решение только для Windows 8+, вы также можете использовать Windows Password Vault. В основном это было создано для приложений Metro, но также поддерживается для приложений Winform и WPF.
По сути, вам нужно
Добавьте следующую строку в файл проекта внутри первой группы свойств
<TargetPlatformVersion>8.0</TargetPlatformVersion>
Справка
Windows.Security
.- Откройте окно диспетчера ссылок
- Выбрать
Windows
вкладка - Выбрать
Core
дополнительная вкладка - Проверьте
Windows.Security
.
В коде используйте (это vb, но C# эквивалентен)
Dim vault = New Windows.Security.Credentials.PasswordVault() vault.Add(New Windows.Security.Credentials.PasswordCredential(resource, userName, password)) Dim cred = vault.Retrieve(resource, logon) cred.RetrievePassword() Dim pwd = cred.Password
Ссылка:
Здесь есть несколько вариантов.
- Храните их в файле конфигурации в зашифрованном виде
- Сохраните их во внешнем файле, который зашифрован сгенерированным начальным числом. Обфусцируйте код, который хранит это базовое начальное число, или сохраните его в dll C++ (сложно декомпилировать).