0

我使用 API 调用来advapi32.dll管理 Windows 保存的凭据,以便自动化某些可以使用保存的凭据的 Windows 应用程序,这工作正常。

我正在尝试更新我的代码以SecureString始终用于密码,因为我不需要在任何时候与密码中包含的文本进行交互,因此如果我的应用程序从不以纯文本形式保存密码,它应该更安全。

我能够将 SecureString 编组到 COM 任务分配器内存以传递给 API 调用:

var unmanagedPassword = Marshal.SecureStringToCoTaskMemUnicode(userCredential.Password);

SecureString但是,当将该信息读回应用程序时,如果不将字符串复制到托管内存中,无论是作为字符串还是字节数组,我都找不到将这种非托管字符串编组回 a 的方法。

有没有一种我忽略的安全方法可以做到这一点?

4

1 回答 1

0

非常感谢Jeroen Mostert的评论导致了这个解决方案,它应该尽可能安全。

正如 Jeroen 所描述的,每个字符都被读取为 ashort并一次附加到一个新字符SecureString

任务分配器内存中的非托管字符串以 null 结尾,因此读取字符直到0. 非托管二进制字符串以长度为前缀,因此需要对下面的代码稍作修改。

    var outString = new SecureString();
    outString.AppendChar('p');
    outString.AppendChar('a');
    outString.AppendChar('s');
    outString.AppendChar('s');
    outString.AppendChar('w');
    outString.AppendChar('o');
    outString.AppendChar('r');
    outString.AppendChar('d');
    var ptr = Marshal.SecureStringToCoTaskMemUnicode(outString);

    var inString = new SecureString();
    var i = 0;
    short c;

    while ((c = Marshal.ReadInt16(ptr, i)) != 0)
    {
        inString.AppendChar((char)c);
        i += 2;
    }

    Marshal.ZeroFreeCoTaskMemUnicode(ptr);
于 2017-09-05T20:35:59.860 回答