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

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

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

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

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

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

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

4 ответа

Решение

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

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

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, его сможет получить любой, у кого есть доступ к машине.

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

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

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

Другие вопросы по тегам