6

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

据我了解,我可以SecureString用来存储密码。但是要以我的管理员帐户运行代码,我有 use WindowsIdentity.Impersonate,并且要使用它,我必须从中获取一个令牌,LogonUser该令牌需要常规string而不是SecureString.

所以我必须:

  1. 启动时登录

  2. 将输入转换为SecureString

  3. 清除输入

然后稍后当我想执行需要提升的功能时:

  1. 将之前创建的转换SecureStringstring

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

  3. 清除转换字符串为null

  4. 执行命令

  5. 清除LogonUser对象

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

编辑:修复了 LogonUser 的名称

4

1 回答 1

7

在您的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);
 }
于 2015-01-08T23:39:53.133 回答