Подтвердить что ты не робот

Как хранить пароли в приложении Winforms?

У меня есть такой код, как это в приложении winforms, которое я писал, чтобы запросить почтовый ящик для хранения данных в хранилище.

DirectoryEntry mbstore = new DirectoryEntry(
      @"LDAP://" + strhome, 
      m_serviceaccount, 
      [m_pwd], 
      AuthenticationTypes.Secure);

Независимо от того, какой подход я попробовал (например, SecureString), я легко могу видеть пароль (m_pwd) либо с помощью Reflector, либо с помощью вкладки строк Process Explorer для исполняемого файла.

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

Может кто-нибудь предложить разумно безопасный способ хранения пароля в локальном приложении, не раскрывая пароль для хакеров?

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

4b9b3361

Ответ 1

Освященный метод - использовать CryptoAPI и API защиты данных.

Чтобы зашифровать, используйте что-то вроде этого (С++):

DATA_BLOB blobIn, blobOut;
blobIn.pbData=(BYTE*)data;
blobIn.cbData=wcslen(data)*sizeof(WCHAR);

CryptProtectData(&blobIn, description, NULL, NULL, NULL, CRYPTPROTECT_LOCAL_MACHINE | CRYPTPROTECT_UI_FORBIDDEN, &blobOut);
_encrypted=blobOut.pbData;
_length=blobOut.cbData;

Расшифровка - это обратное:

DATA_BLOB blobIn, blobOut;
blobIn.pbData=const_cast<BYTE*>(data);
blobIn.cbData=length;

CryptUnprotectData(&blobIn, NULL, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &blobOut);

std::wstring _decrypted;
_decrypted.assign((LPCWSTR)blobOut.pbData,(LPCWSTR)blobOut.pbData+blobOut.cbData/sizeof(WCHAR));

Если вы не укажете CRYPTPROTECT_LOCAL_MACHINE, тогда зашифрованный пароль может быть надежно сохранен в реестре или файле конфигурации, и вы сможете его расшифровать. Если вы укажете LOCAL_MACHINE, тогда любой, у кого есть доступ к машине, сможет его получить.

Ответ 2

Как уже упоминалось, API защиты данных - это хороший способ сделать это. Обратите внимание: если вы используете .NET 2.0 или выше, вам не нужно использовать P/Invoke для вызова DPAPI. Структура обертывает вызовы классом System.Security.Cryptography.ProtectedData.

Ответ 3

Я нашел эту книгу от keith Brown. Руководство разработчика .NET для Windows Security. В нем есть несколько хороших образцов, охватывающих все виды сценариев безопасности. Бесплатно Онлайн-версия также доступна.

Ответ 4

Если вы сохраните его как защищенную строку и сохраните защищенную строку в файле (возможно, используя изолированное хранилище, единственный раз, когда вы будете есть простой текстовый пароль, когда вы расшифровываете его для создания своего mbstore. К сожалению, конструктор не принимает объект SecureString или Credential.