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

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

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

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

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

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

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


person Gulzar Nazim    schedule 02.09.2008    source источник


Ответы (4)


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

person 1800 INFORMATION    schedule 02.09.2008

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

person Michael Petrotta    schedule 30.09.2008
comment
@m_oLogin: см. один из моих других ответов здесь - person Michael Petrotta; 30.06.2010

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

person Gulzar Nazim    schedule 07.09.2008

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

person Steven Murawski    schedule 02.09.2008