все, я столкнулся с проблемой с функцией 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
.
Как отметил Алекс К, есть пример использования 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, которые вы пишете.
SecureStringToGlobalAllocUnicode
имеет полный пример для вызоваLogonUser
: msdn.microsoft.com/en-us/library/...LogonUser
для Ansi, но я не могу сказать наверняка, поскольку вы не указали свою подпись P / Invoke.