C # Call LogonUser сбой с SecureString

1

все, я столкнулся с проблемой с функцией LogonUser.

Я просто хочу знать, могу ли я импортировать функцию LogonUser в С# с помощью этой подписи:

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

Потому что я хочу защитить свой пароль, не используя строку, а класс SecureString. Затем функция используется, как показано ниже:

var passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(password);
var result = LogonUser(userName, domain, passwordPtr, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token);

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

Пожалуйста, помогите мне в том, чтобы защитить пароль с помощью SecureString.

  • 0
    Вот как вы могли бы сделать это .. страница MSDN для SecureStringToGlobalAllocUnicode имеет полный пример для вызова LogonUser : msdn.microsoft.com/en-us/library/...
  • 0
    Очевидная проблема может возникнуть, если вы неправильно указали подпись P / Invoke и пытаетесь передать текст Unicode в версию LogonUser для Ansi, но я не могу сказать наверняка, поскольку вы не указали свою подпись P / Invoke.
Показать ещё 1 комментарий
Теги:
security
winapi

1 ответ

2
Лучший ответ

Как отметил Алекс К, есть пример использования LogonUser в SecureStringToGlobalAllocUnicode. Обратите внимание, что в заявлении P/Invoke есть:

[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);

И этот CharSet = CharSet.Unicode указан. К сожалению, по историческим причинам значение CharSet по умолчанию - Ansi и поэтому ваша попытка P/Invoke будет использоваться.

Это будет отлично для параметра username поскольку инфраструктура P/Invoke гарантирует, что она правильно преобразует string. Но это не соответствует параметру password поскольку вы уже выполнили преобразование строк, и вы сделали это как Unicode - и все, что P/Invoke видит, это IntPtr.

Я предлагаю обновить вашу подпись P/Invoke, чтобы она соответствовала заданной в примере.


Другой альтернативой было бы перейти на использование SecureStringToGlobalAllocAnsi и оставить свою подпись P/Invoke. Но это серьезно второе решение. Написание кода, не поддерживающего Unicode, в 2015 году серьезно не рекомендуется.

Просто привыкните всегда указывать CharSet.Unicode в любых подписях P/Invoke, которые вы пишете.

  • 0
    Спасибо Damien_The_Unbeliever и Alex K. Я попытался обновить подпись с помощью charset до Unicode, и теперь она работает нормально. Я просто не реализовал эти настройки и много раз сравнивал сигнатуру функции в статье, которую упоминал Алекс К :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню