C# 正在内存系统中燃烧。字符串
我试图从内存中删除正常字符串的任何痕迹,为此,我从正常字符串的引用中创建了C# 正在内存系统中燃烧。字符串,c#,.net,string,securestring,C#,.net,String,Securestring,我试图从内存中删除正常字符串的任何痕迹,为此,我从正常字符串的引用中创建了SecureString的实例。像这样: public static unsafe void Burn(this string input) { fixed (char* c = input) { var secure = new SecureString(c, input.Length); secure.Dispose(); } } 问题是,即使在调用dispos
SecureString
的实例。像这样:
public static unsafe void Burn(this string input)
{
fixed (char* c = input)
{
var secure = new SecureString(c, input.Length);
secure.Dispose();
}
}
问题是,即使在调用dispose方法之后,input
的内容也不会更改。据我所知,SecureString
实例应该引用输入
地址,因此在调用Dispose()
时从内存中清除if。我缺少什么?它似乎不适合您的代码使用。文档不清楚,但是它使用短语从系统的子数组初始化SecureString类的新实例。Char对象告诉我它可能在复制数据,而不是对现有字符串进行加密。这是有意义的,因为SecureString
的文档特别提到String
不能以确定的方式销毁
测试这一理论的一个好方法是比较输入
和安全
的地址,看看它们在初始化后是否仍然指向内存中的同一位置。它似乎不适合您的代码使用。文档不清楚,但是它使用短语从系统的子数组初始化SecureString类的新实例。Char对象告诉我它可能在复制数据,而不是对现有字符串进行加密。这是有意义的,因为SecureString
的文档特别提到String
不能以确定的方式销毁
测试这一理论的一个好方法是比较输入
和安全
的地址,看看它们在初始化后是否仍然指向内存中的同一位置。这并不是真正的答案,因为无法确定字符串是否仍在内存中的某个位置浮动,但我想我会发布这个,因为它确实修改了调用它的原始字符串
通过测试您的示例代码,我得出了这个结论。不保证它不会泄漏内存,但它会“烧掉”调用字符串。不过,您的字符串可能仍在其他地方的内存中浮动 这并不是真正的答案,因为无法确定字符串是否仍在内存中的某个位置浮动,但我想我会发布此消息,因为它确实修改了调用它的原始字符串
通过测试您的示例代码,我得出了这个结论。不保证它不会泄漏内存,但它会“烧掉”调用字符串。不过,您的字符串可能仍在其他地方的内存中浮动 string
对象是共享的。谁知道代码引用的是输入
字符串是什么?安全决策可以基于此
因此,字符串在.NET中必须始终是不可变的。您不能(以文档化的方式)删除其内容
input
甚至可能引用字符串文字!如果更改其内容,则不相关代码中的文字可能会更改其值。您可以编写“x”
,并在运行时获取“\0”
。这太可怕了
此外,GC可以移动对象。你的秘密数据可能已经泄露到了整个堆中。构建应用程序时,不需要销毁数据,或者只将其存储在固定/非托管缓冲区中。string
对象是共享的。谁知道代码引用的是输入
字符串是什么?安全决策可以基于此
因此,字符串在.NET中必须始终是不可变的。您不能(以文档化的方式)删除其内容
input
甚至可能引用字符串文字!如果更改其内容,则不相关代码中的文字可能会更改其值。您可以编写“x”
,并在运行时获取“\0”
。这太可怕了
此外,GC可以移动对象。你的秘密数据可能已经泄露到了整个堆中。构建应用程序时,不需要销毁数据,或者只将其存储在固定/非托管缓冲区中。它仍然存在,因为input
仍然存在。您已经处理了SecureString
,但没有处理原始传入的input
字符串。我认为如果你真的想处理字符串
,你必须从安全字符串
开始。而且,如果你这样做是为了摆脱密码的字符串
实例,那你就错了即使您成功地执行了您想要的操作(即使用指针并重写字符串的内容),也不能保证它只是字符串的副本(即GC可能移动了对象10次,并在内存中留下了所有的跟踪)。另外,不要忘了源代码中的字符串是内部的,所以要小心清理这些字符串(不太可能是您想要做的,但请记住)。它仍然存在,因为input
仍然存在。您已经处理了SecureString
,但没有处理原始传入的input
字符串。我认为如果你真的想处理字符串
,你必须从安全字符串
开始。而且,如果你这样做是为了摆脱密码的字符串
实例,那你就错了即使您成功地执行了您想要的操作(即使用指针并重写字符串的内容),也不能保证它只是字符串的副本(即GC可能移动了对象10次,并在内存中留下了所有的跟踪)。另外,别忘了源代码中的字符串是被截取的,所以要小心清理它们(不太可能是你想要做的,但要记住)。是的,检查两个变量的内存地址是我尝试的第一件事,事实上它们并不指向同一个位置。安全
不可能有
public static class StringTest
{
public static unsafe void Burn(this string input)
{
fixed (char* c = input)
{
Marshal.Copy(new string('\0', input.Length).ToCharArray(), 0, new IntPtr(c), input.Length);
}
}
}