我想尽可能地将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字符数.如果不在内存中复制值(从而危及安全性),最好的方法是什么?我计划尽快清零并释放字节数组.
最佳答案 据我所知,大多数Windows API处理UTF-16代码点 – 换句话说,您将代理对视为两个代码点而不是单个字符.鉴于SecureString的构造函数正在处理指向.NET System.Char值(UTF-16)的指针,我认为你得到的代码片段很好 – pbData中的元素数量是字节大小的一半.
例如,如果pbData包含(仅)代理对,则cbData将为4,并且您仍然希望传入2作为第二个参数 – 因为这是您构建SecureString的System.Char值的数量.它是一个非BMP unicode字符的事实与它所代表的UTF-16 System.Char值的数量无关.
(是的,对非BMP数据的支持有点混乱,我怀疑很少有人能在任何地方做到这一点.我相信我没有.幸运的是在很多地方你都不用担心. ..)