简体   繁体   English

在内存中刻录System.String

[英]Burning in memory System.String

I am trying to remove any traces of a normal string from memory, to do so I am creating an instance of SecureString from a reference of the normal string. 我试图从内存中删除任何正常字符串的痕迹,为此,我正在从正常字符串的引用中创建SecureString的实例。 Like so: 像这样:

public static unsafe void Burn(this string input)
{
    fixed (char* c = input)
    {
        var secure = new SecureString(c, input.Length);
        secure.Dispose();
    }
}

The problem is that even after calling the dispose method the contents of input are non-changed. 问题在于,即使在调用dispose方法之后, input的内容也不会更改。 From my understanding the SecureString instance should reference the input address and therefore clean if from memory upon Dispose() call. 据我了解, SecureString实例应该引用input地址,因此如果在调用Dispose()时从内存中清除,则应将其清除。 What am I missing? 我想念什么?

It appears the two parameter constructor is not meant to be used by your code. 看来这两个参数构造函数并不意味着您的代码将使用它。 The documentation isn't clear but its use of the phrase Initializes a new instance of the SecureString class from a subarray of System.Char objects tells me it's probably copying the data, not encrypting the existing string in place. 该文档尚不清楚,但它使用的短语Initializes a new instance of the SecureString class from a subarray of System.Char objects告诉我它可能是在复制数据,而不是就地加密现有字符串。 This would make sense since the documentation for SecureString specifically mentions a String cannot be destroyed in a deterministic way. 这是有道理的,因为SecureString的文档特别提到了不能以确定性的方式销毁String情况。

A good way to test this theory would be to compare the addresses of input and secure to see if they still point to the same location in memory after the initialization. 检验该理论的一个好方法是比较input的地址和secure以查看初始化后它们是否仍指向内存中的同一位置。

string objects are shared. string对象是共享的。 Who knows what is code is referencing that input string? 谁知道引用该input字符串的代码是什么? Security decisions could be based on it. 安全决策可以基于此。

Therefore, strings must always be immutable in .NET. 因此,字符串在.NET中必须始终是不变的。 You cannot kill its contents (in a documented way). 您不能杀死它的内容(以书面形式)。

input might even refer to a string literal! input甚至可能引用字符串文字! If you change its contents, literals in unrelated code might change their value. 如果更改其内容,则无关代码中的文字可能会更改其值。 You write "x" and get "\\0" at runtime. 您写"x"并在运行时获取"\\0" This is so horrible. 太恐怖了

Furthermore, the GC can move objects around. 此外,GC可以移动对象。 Your secret data has probably leaked all over the heap already. 您的秘密数据可能已经泄漏到整个堆中。 Construct your app in such a way that it does not require destroying data, or only store it in pinned/unmanaged buffers. 以无需销毁数据或仅将其存储在固定/非托管缓冲区中的方式构建应用。

This isn't really meant as an answer as there is no way to determine that the string isn't still floating in memory somewhere, but I thought I would post this because it does modify the original string that it was called on. 这并不是真正的答案,因为无法确定该字符串是否仍未在内存中的某个位置浮动,但是我认为我会发布此消息,因为它确实会修改被调用的原始字符串。


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

Testing your sample code, I was able to come up with this. 测试您的示例代码,我能够想到这一点。 No guarantees that it doesn't leak memory, but it does "burn" the calling string. 不保证它不会泄漏内存,但是会“燃烧”调用字符串。 Your string may still be floating in memory somewhere else though. 但是,您的字符串可能仍在其他地方的内存中浮动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM