Где хранить пароли БД при использовании приложений 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:

Для примеров кода и в случае, если вы заинтересованы в шифровании частей файла.config приложений, проверьте это:

Я рекомендую вам использовать соль (то есть, используя optionalEntropy параметр) - защищает от атак на радужные таблицы.


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

Это хороший вопрос, и я сам искал ответ. У меня была проблема с безопасностью паролей БД на случай взлома сервера и получения отдельных файлов. Одна очень интересная опция, которую я нашел, заключалась в том, что разделы web.config могут быть зашифрованы и расшифрованы автоматически на лету.NET Framework, который будет использовать безопасное хранилище Windows для хранения и получения ключа шифрования для вас. В моей ситуации это было недоступно, потому что мой хостинг-провайдер не поддерживал его, но вы можете посмотреть на эту опцию. Я думаю, что это может сработать, потому что вы можете самостоятельно управлять безопасностью пользователей, которые могут получить доступ к безопасному хранилищу Windows, и значительно ограничивать любые потенциальные нарушения. Хакер, взломавший сервер, может получить копию ваших файлов конфигурации и всех ваших сборок, но доступ к ключу расшифровки будет для него еще одним препятствием.

Если вы используете решение только для Windows 8+, вы также можете использовать Windows Password Vault. В основном это было создано для приложений Metro, но также поддерживается для приложений Winform и WPF.

По сути, вам нужно

  1. Добавьте следующую строку в файл проекта внутри первой группы свойств
    <TargetPlatformVersion>8.0</TargetPlatformVersion>

  2. Справка Windows.Security.

    • Откройте окно диспетчера ссылок
    • Выбрать Windows вкладка
    • Выбрать Core дополнительная вкладка
    • Проверьте Windows.Security.
  3. В коде используйте (это 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
    

Ссылка:

  1. https://docs.microsoft.com/fr-ca/archive/blogs/cdndevs/using-windows-8-winrt-apis-in-net-desktop-applications
  2. https://docs.microsoft.com/en-us/uwp/api/Windows.Security.Credentials.PasswordVault?view=winrt-19041

Здесь есть несколько вариантов.

  1. Храните их в файле конфигурации в зашифрованном виде
  2. Сохраните их во внешнем файле, который зашифрован сгенерированным начальным числом. Обфусцируйте код, который хранит это базовое начальное число, или сохраните его в dll C++ (сложно декомпилировать).
Другие вопросы по тегам