将SecureString与LogonUser一起使用

duc*_*zle 6 .net c# security securestring

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

据我所知,我可以SecureString用来存储密码.但是为了运行代码作为我的管理员帐户,我已经使用了WindowsIdentity.Impersonate,并且要使用我必须得到一个令牌,LogonUser从中需要常规string而不是SecureString.

所以我必须:

  1. 在启动时登录

  2. 将输入转换为 SecureString

  3. 清除输入

然后,当我想要执行需要提升的函数时:

  1. 将先前创建的转换SecureStringstring

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

  3. 清除转换字符串 null

  4. 执行命令

  5. 清除LogonUser对象

这是接近这个的正确方法吗?这似乎不可思议必须有转换的SecureStringstring使用它...好像它会破坏的目的,并留下密码更容易,而我将它转换.

编辑:修复了LogonUser的名称

Ili*_*ian 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);
 }
Run Code Online (Sandbox Code Playgroud)