2017-02-10 109 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不會(有意地)做任何事情來清理前一個內存位置) –