从非托管unicode字符串创建SecureString

时间:2009-02-04 21:02:20

标签: c# unicode pinvoke marshalling securestring

我想尝试尽可能最好地将CryptUnprotectData窗口API函数和.net SecureString绑定在一起。 CryptUnprotectData返回DATA_BLOB结构,该结构由字节数组和字节长度组成。在我的程序中,这将是Unicode UTF-16字符串。 SecureString有一个构造函数,它接受char *和length params,所以我希望能够做类似的事情:

SecureString ss = SecureString((char*)textBlob.pbData, textBlob.cbData / 2);

这是有效的,除了UTF-16是可变长度的,所以我真的不知道使用什么作为长度参数。上面的示例假定为2个字节字符(BMP),但对于其他平面,它可能最多为4个字节。我需要知道字节数组中的UTF-16字符数。如果不在内存中复制值(从而危及安全性),最好的方法是什么?我计划尽可能快地将字节数组清零并释放。

1 个答案:

答案 0 :(得分:2)

据我所知,大多数Windows API处理UTF-16代码点 - 换句话说,您将代理对视为两个代码点而不是单个字符。鉴于SecureString的构造函数正在处理指向.NET System.Char值(UTF-16)的指针,我认为你得到的代码片段很好 - pbData 中的元素数量是< / em>以字节为单位的一半大小。

例如,如果pbData包含(仅)一个代理项对,cbData将为4,您仍然希望传入2作为第二个参数 - 因为这是{{1您正在构建System.Char的值。它是一个非BMP unicode字符的事实与它所代表的UTF-16 SecureString值的数量无关。

(是的,对非BMP数据的支持有点混乱,我怀疑很少有人能在任何地方做到这一点。我相信我没有。幸运的是在许多地方你不需要担心...)