我想尝试尽可能最好地将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字符数。如果不在内存中复制值(从而危及安全性),最好的方法是什么?我计划尽可能快地将字节数组清零并释放。
答案 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数据的支持有点混乱,我怀疑很少有人能在任何地方做到这一点。我相信我没有。幸运的是在许多地方你不需要担心...)