清除带有敏感数据的c#字节数组

时间:2009-08-24 03:22:22

标签: c# passwords

我有一个包含敏感数据的c#byte []。 清除它的最佳方法是什么? 我如何确保不会优化像Array.Clear这样的东西?

7 个答案:

答案 0 :(得分:9)

我无法想到任何调用Array.Clear的情况会被优化掉的情况,即使它可能只会在已经清除byte[]的情况下进行优化。

编辑:要考虑的其他事项是找出框架的SecureString实施是否对您的情况有用:

  

SecureString对象类似于a   String对象,因为它有一个文本   值。但是,a的价值   SecureString对象是自动的   加密,可以修改,直到你的   应用程序将其标记为只读,并且   可以从计算机内存中删除   您的应用程序或.NET   框架垃圾收集器

答案 1 :(得分:4)

即使Array.Clear被保证执行(没有优化)我认为你仍然可能有问题。 GC可以在堆中移动对象,并且如果在调用Array.Clear之前将原始字节的跟踪从一个位置移动到另一个位置,则无法保证原始字节的跟踪将会延迟。

您可以查看SecureStringProtectedDataProtectedMemory。但是,如果你想要一个更手动的方法,我认为你必须至少固定字节数组,以便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%的数据。您必须清除整个密钥路径。