.NET安全内存结构

Nic*_*ick 9 c# memory security object

我知道.NET库提供了一种以受保护/安全的方式存储字符串的方法= SecureString.

我的问题是,如果我想存储一个字节数组,那么保存这个数据的最佳,最安全的容器是什么?

Han*_*ant 11

了解System.String类型的漏洞非常重要.不可能使其完全安全,SecureString的存在可以最大限度地降低暴露风险.System.String存在风险,因为:

  • 它们的内容在其他地方可见,无需使用调试器.攻击者可以查看分页文件(c:\ pagefile.sys),它保留了换成磁盘的RAM页面的内容,为其他需要RAM的程序腾出空间
  • System.String是不可变的,您在使用它之后无法擦除字符串的内容
  • 垃圾收集堆会压缩堆,但不会重置已释放的内存的内容.哪个可以将字符串数据的副本留在内存中,完全无法从程序中获取.

这里明显的风险是字符串内容在使用字符串后很久就可见,因此大大增加了攻击者可以看到它的几率.SecureString通过将字符串存储在非托管内存中来提供一种解决方法,在该内存中,它不受垃圾收集器的影响,不会留下字符串内容的杂散副本.

现在应该清楚如何使用SecureString提供的相同类型的保证来创建自己的安全阵列版本.您没有不可变性问题,在使用它之后擦除阵列不是问题.这本身几乎总是足够好,隐含在减少暴露的可能性是你不会长时间保持对数组的引用.因此,在垃圾收集之后存在的阵列数据的非擦除副本的可能性应该已经很低.您也可以降低该风险,仅适用于小于85,000字节的数组.通过SecureString执行它并使用Marshal.AllocHGlobal()的方式.或者通过固定数组GCHandle.Alloc()更容易.


Nic*_*rdi 1

您可以使用 SecureString 来存储字节数组。

  SecureString testString = new SecureString();

  // Assign the character array to the secure string.
  foreach (byte b in bytes)
     testString.AppendChar((char)b);
Run Code Online (Sandbox Code Playgroud)

然后你只需反转该过程即可取回字节。


这不是唯一的方法,您始终可以使用 MemoryBuffer 和 System.Security.Cryptography 中的某些内容。但这是唯一专门设计用于以这种方式确保安全的东西。您必须使用 System.Security.Cryptography 创建所有其他内容,这可能是您的最佳方法。