如何将一个securestring编组为非托管代码?

时间:2009-10-02 07:00:47

标签: c# .net unmanaged marshalling

是什么促成了这个问题: 我正在尝试更改运行Windows服务的帐户。我决定使用win32 api而不是WMI,并开始查看ChangeServiceConfig。

我认为我可以在非托管方法签名中使用SecureString类型,它可以正常工作。嗯,不太好。这让我想知道,有没有人知道什么本机(win32)类型的SecureString类被编组为(默认情况下)非托管代​​码?

4 个答案:

答案 0 :(得分:5)

我从来没有得到标题中问题的答案,所以我仍然不知道SecureString被编组为非托管代码。

但是,我确实通过使用其他一些答案中的建议来使我的代码工作。我已经提供了以下代码。

internal static class NativeService
{
    ...
    [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool ChangeServiceConfig(IntPtr hService, uint nServiceType, uint nStartType, uint nErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, IntPtr lpdwTagId, [In] char[] lpDependencies, string lpServiceStartName, IntPtr lpPassword, string lpDisplayName);
    ...
    public const uint SERVICE_NO_CHANGE = 0xffffffff;
}

internal class ClassThatConfiguresService
{
    ...
    public void ConfigureStartupAccount(IntPtr service, string userName, SecureString password)
    {
        passwordPointer = Marshal.SecureStringToGlobalAllocUnicode(password);
        try
        {
            if(!NativeService.ChangeServiceConfig(service, NativeService.SERVICE_NO_CHANGE, NativeService.SERVICE_NO_CHANGE, NativeService.SERVICE_NO_CHANGE, null, null, IntPtr.Zero, null, userName, passwordPointer, null))
                throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        finally
        {
            Marshal.ZeroFreeGlobalAllocUnicode(passwordPointer);
        }
    }
    ...
}

我使用的是Marshal.SecureStringToGlobalAllocUnicode,而不是Marshal.SecureStringToGlobalAllocUnicode,因为这是非托管函数所期望的,但除此之外它还可以用来处理。

希望其他人觉得这很有用。 KEP。

答案 1 :(得分:4)

看起来您可以使用InteropServices命名空间中的帮助函数来帮助您:

  

请注意,SecureString没有成员   检查,比较或转换   SecureString的值。缺席的   这些成员有助于保护   意外的实例值   或恶意曝光。使用适当   成员   System.Runtime.InteropServices .. ::。元帅   class,例如SecureStringToBSTR   方法,来操纵a的值   SecureString对象。

您可以使用SecureStringToBSTR将字符串转换为BSTR,然后将其传递给适当的函数以供使用。

答案 2 :(得分:2)

答案 3 :(得分:0)

SecureString是non-blittable类型。所以 - 没有1:1的win32类型。

请记住,我根本不是COM专家。