Использование SecureString с LogonUser

В учебных целях я пишу свой собственный клиент Active Directory. Чтобы выполнять такие команды, как разблокировка учетных записей и сброс паролей, я должен ввести свою учетную запись администратора и пароль, а также использовать и WindowsIdentity.Impersonate запустить код в качестве своей учетной записи администратора. Меня интересуют мои варианты защиты моего пароля, так как он должен использоваться много раз в моей программе.

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

Итак, мне пришлось бы:

  1. Вход при запуске

  2. Преобразование ввода в SecureString

  3. Очистить ввод

Затем позже, когда я хочу предварительно сформировать функцию, требующую повышения:

  1. Преобразование ранее созданного SecureString в string

  2. Передайте преобразованную строку в LogonUser

  3. Очистить строку преобразования в null

  4. Выполнить команду

  5. Очистить объект LogonUser

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

РЕДАКТИРОВАТЬ: Исправлено имя для LogonUser


person duckwizzle    schedule 08.01.2015    source источник
comment
Вы правы в том, что преобразование в строку побеждает цель. Что такое олицетворение пользователя? Это PInvoke для Win32 API? Возможно, вам придется изменить функцию, которую он использует для передачи IntPtr вместо строки.   -  person Ilian    schedule 09.01.2015
comment
Ой, извините... Я исправлю свой вопрос. Да, UserImpersonation — это класс, который я написал давным-давно... по сути, это оболочка для LogonUser , который также запрашивает строку для пароля. Можно ли изменить это на IntPtr ? Если это так, могу ли я вместо этого просто передать SecureString в параметр пароля? (Я бы попробовал сейчас, но я больше не на работе...)   -  person duckwizzle    schedule 09.01.2015
comment
Нет, вы не можете использовать SecureString напрямую, но безопасно передать пароль не составит труда. отвечу ниже...   -  person Ilian    schedule 09.01.2015


Ответы (1)


В своем классе UserImpersonation измените способ объявления LogonUser, чтобы использовать IntPtr вместо string для пароля.

Пример кода для В Marshal.SecureStringToGlobalAllocUnicode есть именно то, что вам нужно. Вот соответствующий фрагмент:

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool LogonUser(String username, String domain,
                                      IntPtr password, int logonType,
                                      int logonProvider, ref IntPtr token);

...

IntPtr tokenHandle = IntPtr.Zero;

IntPtr passwordPtr = IntPtr.Zero;

try
{
    // Marshal the SecureString to unmanaged memory.
    passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(password);

    returnValue = LogonUser(userName, domainName, passwordPtr,
                            LOGON32_LOGON_INTERACTIVE,
                            LOGON32_PROVIDER_DEFAULT, ref tokenHandle);

 }
 finally
 {
     // Zero-out and free the unmanaged string reference.
     Marshal.ZeroFreeGlobalAllocUnicode(passwordPtr);

     // Close the token handle.
     CloseHandle(tokenHandle);
 }
person Ilian    schedule 08.01.2015
comment
Идеальный! Благодарю вас! :) - person duckwizzle; 09.01.2015
comment
@duckwizzle Не беспокойтесь - person Ilian; 10.01.2015