将 SecureString 与 LogonUser 一起使用
Using SecureString with LogonUser
出于学习目的,我正在编写自己的 Active Directory 客户端。为了执行解锁帐户和重置密码等命令,我必须输入我的管理员帐户和密码并使用 WindowsIdentity.Impersonate
以我的管理员帐户运行代码。我想知道我保护密码的选项,因为它必须在我的程序中多次使用。
据我了解,我可以使用SecureString
来存储密码。但是要以我的管理员帐户运行代码,我使用了 WindowsIdentity.Impersonate
,并且要使用它我必须从 LogonUser
获取令牌,这需要常规的 string
而不是 SecureString
。
所以我必须:
启动时登录
将输入转换为 SecureString
清除输入
然后当我想执行一个需要提升的函数时:
将之前创建的SecureString
转换为string
将转换后的字符串传给LogonUser
清除转换字符串为null
执行命令
清除 LogonUser
对象
这是解决这个问题的正确方法吗?必须将 SecureString
转换为 string
才能使用它似乎很奇怪......似乎它会破坏目的并在我转换密码时使密码更容易受到攻击。
编辑:修复了 LogonUser
的名称
在您的 UserImpersonation
class 中,更改声明 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);
}
出于学习目的,我正在编写自己的 Active Directory 客户端。为了执行解锁帐户和重置密码等命令,我必须输入我的管理员帐户和密码并使用 WindowsIdentity.Impersonate
以我的管理员帐户运行代码。我想知道我保护密码的选项,因为它必须在我的程序中多次使用。
据我了解,我可以使用SecureString
来存储密码。但是要以我的管理员帐户运行代码,我使用了 WindowsIdentity.Impersonate
,并且要使用它我必须从 LogonUser
获取令牌,这需要常规的 string
而不是 SecureString
。
所以我必须:
启动时登录
将输入转换为
SecureString
清除输入
然后当我想执行一个需要提升的函数时:
将之前创建的
SecureString
转换为string
将转换后的字符串传给
LogonUser
清除转换字符串为
null
执行命令
清除
LogonUser
对象
这是解决这个问题的正确方法吗?必须将 SecureString
转换为 string
才能使用它似乎很奇怪......似乎它会破坏目的并在我转换密码时使密码更容易受到攻击。
编辑:修复了 LogonUser
的名称在您的 UserImpersonation
class 中,更改声明 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);
}