将 COM 任务分配器内存中的非托管 Unicode 字符串编组到 SecureString
Marshal Unmanaged Unicode String in COM Task Allocator Memory to SecureString
我正在使用 API 调用 advapi32.dll
来管理 Windows 已保存的凭据,以便自动执行某些可以使用已保存凭据的 windows 应用程序,这是有效的很好。
我正在尝试更新我的代码以在整个过程中使用 SecureString
作为密码,因为我在任何时候都不需要与密码中包含的文本进行交互,因此如果我的应用程序永远不会持有它应该会更安全明文密码。
我能够将 SecureString 编组到 COM 任务分配器内存以传递给 API 调用:
var unmanagedPassword = Marshal.SecureStringToCoTaskMemUnicode(userCredential.Password);
但是,当涉及将该信息读回应用程序时,我无法找到一种方法将此类非托管字符串编组回 SecureString
而不将字符串复制到托管内存中,无论是作为字符串或字节数组。
有没有我忽略的安全方法?
非常感谢 Jeroen Mostert 提出这个解决方案的评论,它应该尽可能安全。
正如 Jeroen 所描述的,每个字符都被读取为一个 short
并一次附加到一个新的 SecureString
。
任务分配器内存中的非托管字符串以空值终止,因此读取字符直到获得 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);
我正在使用 API 调用 advapi32.dll
来管理 Windows 已保存的凭据,以便自动执行某些可以使用已保存凭据的 windows 应用程序,这是有效的很好。
我正在尝试更新我的代码以在整个过程中使用 SecureString
作为密码,因为我在任何时候都不需要与密码中包含的文本进行交互,因此如果我的应用程序永远不会持有它应该会更安全明文密码。
我能够将 SecureString 编组到 COM 任务分配器内存以传递给 API 调用:
var unmanagedPassword = Marshal.SecureStringToCoTaskMemUnicode(userCredential.Password);
但是,当涉及将该信息读回应用程序时,我无法找到一种方法将此类非托管字符串编组回 SecureString
而不将字符串复制到托管内存中,无论是作为字符串或字节数组。
有没有我忽略的安全方法?
非常感谢 Jeroen Mostert 提出这个解决方案的评论,它应该尽可能安全。
正如 Jeroen 所描述的,每个字符都被读取为一个 short
并一次附加到一个新的 SecureString
。
任务分配器内存中的非托管字符串以空值终止,因此读取字符直到获得 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);