将SecureString与LogonUser一起使用

时间:2015-01-08 22:03:40

标签: c# .net security securestring

出于学习目的,我正在编写自己的Active Directory客户端。为了执行解锁帐户和重置密码等命令,我必须输入管理员帐户和密码并使用WindowsIdentity.Impersonate运行代码作为我的管理员帐户。我想知道我保护密码的选项,因为它必须在我的程序中多次使用。

根据我的理解,我可以使用SecureString来存储密码。但是要将代码作为我的管理员帐户运行,我使用了WindowsIdentity.Impersonate,并且要使用我必须从LogonUser获取令牌,这需要定期string而不是SecureString

所以我必须:

  1. 启动时登录

  2. 将输入转换为SecureString

  3. 清除输入

  4. 然后我想要预先形成一个需要提升的函数:

    1. 将之前创建的SecureString转换为string

    2. 将转换后的字符串传递给LogonUser

    3. 将转换字符串清除为null

    4. 执行命令

    5. 清除LogonUser对象

    6. 这是接近这个的正确方法吗?似乎很奇怪,必须将SecureString转换为string才能使用它......似乎它会破坏目的,并在我转换它时使密码更容易受到攻击。

      编辑:修正了LogonUser的名称

1 个答案:

答案 0 :(得分:6)

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