﻿# 使用 SecureString 類別保護你的字串值

我們其實可以透過許多工具取得 .NET 應用程式執行時在記憶體中的資料，例如：[WinDbg](http://en.wikipedia.org/wiki/WinDbg) 或 [Debug Diagnostic Tool](https://www.microsoft.com/en-us/download/details.aspx?id=58210)。而當你在 .NET 程式中需要將一些較機密的資料暫存在變數(物件)時，若單純的使用 [System.String](https://learn.microsoft.com/en-us/dotnet/api/system.security.securestring?view=net-6.0&WT.mc_id=DT-MVP-4015686) 類別建立執行個體(Instance)儲存資料，就很容易被一些除錯工具或傾印(dump)工具取得原始資料，原因是 [System.String](https://learn.microsoft.com/en-us/dotnet/api/system.security.securestring?view=net-6.0&WT.mc_id=DT-MVP-4015686) 類別是不變的(immutable)，且當不再需要它時也無法透過程式排程進行記憶體回收。所以當你使用 [System.String](https://learn.microsoft.com/en-us/dotnet/api/system.security.securestring?view=net-6.0&WT.mc_id=DT-MVP-4015686) 類別儲存文字內容在記憶體中，就很難保證在物件不用了之後能夠即時在記憶體中刪除，這樣的程式就有被資訊揭露([Information Disclosure](http://en.wikipedia.org/wiki/Disclosure))的安全風險。

> 微軟建議不要再使用 [SecureString Class](https://learn.microsoft.com/en-us/dotnet/api/system.security.securestring?view=net-6.0&WT.mc_id=DT-MVP-4015686) 在應用程式中，請參考 [DE0001: SecureString shouldn't be used](https://github.com/dotnet/platform-compat/blob/master/docs/DE0001.md) 分析規則，

如果你的 .NET 應用程式並非執行在自己所能管控的主機上，安全性的考量就更高了，這時你就可以考慮使用 [SecureString 類別](http://msdn.microsoft.com/zh-tw/library/system.security.securestring.aspx)來保護你的字串值。而 [SecureString](http://msdn.microsoft.com/zh-tw/library/system.security.securestring.aspx) 物件與 [String](https://learn.microsoft.com/en-us/dotnet/api/system.security.securestring?view=net-6.0&WT.mc_id=DT-MVP-4015686) 物件的相似之處在於他們儲存的資料都是字串值。不過，[SecureString](http://msdn.microsoft.com/zh-tw/library/system.security.securestring.aspx) 物件的字串值會「自動加密」，而且你也可以在您的 .NET 應用程式中將物件標示為唯讀前進行修改，也可以由應用程式或 .NET Framework 記憶體回收行程將其從電腦記憶體中刪除，這樣就能夠確保你要存取的字串值在記憶體中也能夠受到保護。

因為最近在看 [Windows PowerShell 實戰手冊 (Windows PowerShell in Action)](https://www.tenlong.com.tw/products/9789861813493) 這本書，在第 523 頁提到了個 [SecureString 類別](http://msdn.microsoft.com/zh-tw/library/system.security.securestring.aspx)，感覺蠻不錯的，所以推薦給大家知道。

### 相關連結

-   [SecureString Class](https://learn.microsoft.com/en-us/dotnet/api/system.security.securestring?view=net-6.0&WT.mc_id=DT-MVP-4015686)
-   [DE0001: SecureString shouldn't be used](https://github.com/dotnet/platform-compat/blob/master/docs/DE0001.md)
-   [How to convert SecureString to System.String? - Stack Overflow](https://stackoverflow.com/a/819705/910074)
-   [SecureStringHelper](https://referencesource.microsoft.com/#System/net/System/Net/UnsafeNativeMethods.cs,77e10d03a6d14232)
