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

清除带有敏感数据的c#字节数组,c#,passwords,C#,Passwords,我有一个包含敏感数据的c#字节[]。 最好的清除方法是什么? 我如何确保像Array.Clear这样的东西不会被优化掉?我想不出在什么情况下调用Array.Clear会被优化掉,即使可以,也只会在字节[]已经被清除的情况下被优化掉 > >编辑:>要考虑的其他事项是找出框架的实现是否对您的情况有用: SecureString对象类似于 String对象,因为它有一个文本 价值然而,a的价值 SecureString对象是自动创建的 加密,可以修改,直到您的 应用程序将其标记为只读,并且 可通过以

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

我想不出在什么情况下调用
Array.Clear
会被优化掉,即使可以,也只会在
字节[]
已经被清除的情况下被优化掉

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

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


如果您关心Array.Clear,则始终可以封送。将空字节数组复制到敏感数据上

例如,如下所示(假设“data”是包含敏感信息的字节[]):


我的印象是,已经有了显示RAM最新状态的技术。还有麻省理工学院的人,flash冻结了一些RAM,把它抬起来,带到其他地方,维持了整个州


所以,如果你是偏执狂,你会在数组上随机写入一大堆数据几次。

好吧,在CLR中没有等价物。您应该使用来存储数据。

即使保证执行Array.Clear(而不是优化),我认为您仍然可能有问题。GC可以在堆中移动对象,如果在数组之前将原始字节从一个位置移动到另一个位置,则无法保证原始字节的跟踪会保持不变。已调用Clear


您可能想退房,或者。但是,如果您想要更手动的方法,我认为您至少必须固定字节数组,这样GC就不能移动它。我相信SecureString也使用了这个技巧。

大多数C编译器都使用的一个技巧是对清除数组的所有元素求和,然后对该和进行处理,比如打印或对返回值进行异或。这样,死代码消除不会消除对数组的清除


也就是说,您确定只需要清除此阵列吗?考虑值可能存在的所有其他地方:窗体中的缓冲区、周围的字符串对象、中间计算中的密钥等效值或分页到磁盘。将这一数组归零只会得到1%的结果。您必须清除整个密钥路径。

如果您正在编写自己的加密例程,我的建议是:不要。你会弄错的(我也一样,不是安全专家的人也一样)。使用知名的、经过测试的库


(如果没有,没关系!):)

如果在数组被清除后没有人可以读取它,那么编译器不能通过不清除它来优化吗?作为一个问题:当你说编译器时,你指的是C#编译器还是JIT编译器?他们确实这样做了。但是,该攻击假定可以访问物理系统。深度防御……真正的教训是,你不能向你的客户透露秘密,因为你的客户总是会受到威胁。@Spence:是的,我只是觉得他们这么做太疯狂了。:)@这取决于您的信任模型。对我来说,通常情况正好相反。一、 用户可以控制客户端(至少这是理想的),而我无法验证服务器是否运行良性代码。因此,我的秘密需要保存在客户端上,所有通信都需要端到端加密,以确保服务器无法拦截它们。在某个时候,你需要给图书馆打电话,并且你需要知道如何处理进出图书馆的秘密;否则您无法创建安全软件。@JirkaHanika同意。
        byte[] clear = new byte[data.Length];
        unsafe
        {
            fixed (byte* ptr = &data[0])
            {
                Marshal.Copy(clear, 0, new IntPtr(ptr), data.Length);
            }
        }