2017-02-10 92 views
-1

我想从.NET应用程序的内存中删除一个字符串。 假设我们有一个Decryption方法,它来自第三方库,它返回一个String。这并不聪明,但我无能为力。现在删除字符串的内容

String s = SomeComponent.Decrypt("cypherstring") 

我的s内容复制到SecureString的工作。但是......我该如何摆脱s。我知道GC会收集在这里,但如果我用了一段时间它会留下来。我也想在这里不依赖GC,因为它可能与安全有关 - 这使我的代码具有确定性。

我的想法是这样的事情:

public static SecureString Convert(ref String s) 
{ 
    //copy content of s into SecureString 
    //shred s 
} 

没有什么大不了的复制数据到SecureString的,但我怎么“毁” S?

+0

为什么你认为复制它会更安全?你已经创建了一个新的字符串(s)输出复制到...并且只要它在代码中不再被使用,它就会得到GC'd,所以如果它是一个局部变量,它会很快得到GC'd。 – EpicKip

+0

我想你可以使用'Marshall.DestroyStructure'和'Marshall.FreeHAlloc'来组合你想做的事情,甚至可以用'GC.Collect'去核化,但我同意EpicKip可能没有必要,特别是如果它是一个局部变量。 – Abion47

+0

如果您不想让数据再被读取,您至少可以将s设置为另一个值,因此即使GC目前不处理该数据,原始字符串内容 – Pedro

回答

0

使用此代码:

public static SecureString Convert(ref String s) 
{ 
    //copy content of s into SecureString 
    SecureString secureString; 
    unsafe 
    { 
     fixed (char* charArray = s.ToArray()) 
      secureString = new SecureString(charArray, s.Length); 
    }    
    //shred s 
    s = null; 
    GC.Collect(); 
    return secureString; 
} 

注意,如果字符串不能超过SecureString的最大容量的长度。 SecureString的最大容量是65536

+2

这可能不起作用。从MSDN: “使用此方法尝试回收不可访问的内存。但是,使用此方法并不能保证指定代中的所有无法访问的内存都被回收。“ – Gordon

+0

正如我在其他问题中提到的那样,您不知道该字符串的多少次拷贝可能已经在堆中的(当前未使用的)内存中结束了,因为它在之前的GC期间被”移动“了(当然,当我们在GC中说“移动”时,我们实际上的意思是复制并引用更新.GC不会(有意地)做任何事情来清理前一个内存位置) –