我有一个包含敏感数据的c#byte []。 清除它的最佳方法是什么? 我如何确保不会优化像Array.Clear这样的东西?
答案 0 :(得分:9)
我无法想到任何调用Array.Clear
的情况会被优化掉的情况,即使它可能只会在已经清除byte[]
的情况下进行优化。
编辑:要考虑的其他事项是找出框架的SecureString
实施是否对您的情况有用:
SecureString
对象类似于aString
对象,因为它有一个文本 值。但是,a的价值 SecureString对象是自动的 加密,可以修改,直到你的 应用程序将其标记为只读,并且 可以从计算机内存中删除 您的应用程序或.NET 框架垃圾收集器
答案 1 :(得分:4)
即使Array.Clear被保证执行(没有优化)我认为你仍然可能有问题。 GC可以在堆中移动对象,并且如果在调用Array.Clear之前将原始字节的跟踪从一个位置移动到另一个位置,则无法保证原始字节的跟踪将会延迟。
您可以查看SecureString,ProtectedData或ProtectedMemory。但是,如果你想要一个更手动的方法,我认为你必须至少固定字节数组,以便GC不能移动它。我相信SecureString也使用这个技巧。
答案 2 :(得分:1)
如果你担心Array.Clear,你可能总是Marshal。将一个空的字节数组复制到敏感数据上。
例如,像这样(假设'data'是包含敏感信息的byte []):
byte[] clear = new byte[data.Length];
unsafe
{
fixed (byte* ptr = &data[0])
{
Marshal.Copy(clear, 0, new IntPtr(ptr), data.Length);
}
}
答案 3 :(得分:1)
如果您正在编写自己的加密例程,我的建议是:不要。你会弄错的(和我一样,也不是那些不是安全专家的人)。使用着名的,经过测试的库。
(如果没有,请不要介意!):)
答案 4 :(得分:0)
我的印象是,已经有技术可以显示最近的RAM状态。然后还有麻省理工学院的家伙闪光冻结了一些内存,解除了它并将其带到其他地方并保持了整个状态。
所以,如果你是偏执狂,你会在你的阵列上随机写几堆数据。
答案 5 :(得分:0)
AFAIK在CLR中没有等同于SecureZeroMemory。您应该使用SecureString来存储数据。
答案 6 :(得分:0)
与大多数C编译器一起使用的技巧是对已清除数组的所有元素进行求和,然后对该总和执行某些操作,例如将其打印或使用返回值进行xor处理。这样,死代码消除不会消除数组的清除。
那就是说,你确定你只需要清除这个阵列吗?考虑值也可能存在的所有其他位置:表单中的缓冲区,传递的字符串对象,中间计算中的键等效值或分页到磁盘。将这一个数组归零只能获得1%的数据。您必须清除整个密钥路径。