1

我正在尝试从内存中删除任何普通字符串的痕迹,为此我正在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实例应该引用input地址,因此如果在Dispose()调用时从内存中清除。我错过了什么?

4

3 回答 3

4

看来这两个参数构造函数并不打算由您的代码使用。文档不清楚,但它对短语的使用Initializes a new instance of the SecureString class from a subarray of System.Char objects告诉我它可能是在复制数据,而不是对现有字符串进行加密。这是有道理的,因为SecureString特别提到 a的文档String不能以确定性的方式销毁。

测试这个理论的一个好方法是比较地址inputsecure查看它们在初始化后是否仍然指向内存中的相同位置。

于 2014-02-28T23:46:50.777 回答
2

string对象是共享的。谁知道引用该input字符串的代码是什么?安全决策可以基于它。

因此,字符串在 .NET 中必须始终是不可变的。你不能杀死它的内容(以记录的方式)。

input甚至可能指的是字符串文字!如果您更改其内容,不相关代码中的文字可能会更改其值。您在运行时编写"x"和获取"\0"。这太可怕了。

此外,GC 可以移动对象。您的秘密数据可能已经泄露了整个堆。以不需要破坏数据或仅将其存储在固定/非托管缓冲区中的方式构建您的应用程序。

于 2014-03-01T00:23:05.310 回答
0

这并不是真正的答案,因为无法确定字符串是否仍在内存中的某个地方浮动,但我想我会发布这个,因为它确实修改了调用它的原始字符串。


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);
        }
    }
}

测试您的示例代码,我能够想出这个。不能保证它不会泄漏内存,但它会“烧毁”调用字符串。不过,您的字符串可能仍漂浮在其他地方的内存中。

于 2014-03-01T00:11:43.787 回答