Как хранить пароли в приложении Winforms?
У меня есть такой код, как это в приложении winforms, которое я писал, чтобы запросить почтовый ящик для хранения данных в хранилище.
DirectoryEntry mbstore = new DirectoryEntry(
@"LDAP://" + strhome,
m_serviceaccount,
[m_pwd],
AuthenticationTypes.Secure);
Независимо от того, какой подход я попробовал (например, SecureString
), я легко могу видеть пароль (m_pwd) либо с помощью Reflector, либо с помощью вкладки строк Process Explorer для исполняемого файла.
Я знаю, что могу поместить этот код на сервер или подтянуть систему безопасности с помощью таких механизмов, как делегирование, и предоставить только необходимые привилегии учетной записи службы.
Может кто-нибудь предложить разумно безопасный способ хранения пароля в локальном приложении, не раскрывая пароль для хакеров?
Хеширование невозможно, так как мне нужно знать точный пароль (а не только хэш для соответствия цели).
Механизмы шифрования/дешифрования не работают, так как они зависят от машины.
Ответы
Ответ 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.