SecureString 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
代表應該將文字保密,例如於不再使用時將它從電腦記憶體刪除。 此類別無法獲得繼承。
public ref class SecureString sealed : IDisposable
public sealed class SecureString : IDisposable
type SecureString = class
interface IDisposable
Public NotInheritable Class SecureString
Implements IDisposable
- 繼承
-
SecureString
- 實作
範例
下列範例示範如何使用 SecureString 來保護使用者的密碼,以作為認證來啟動新的程式。
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Security;
public class Example
{
public static void Main()
{
// Instantiate the secure string.
SecureString securePwd = new SecureString();
ConsoleKeyInfo key;
Console.Write("Enter password: ");
do {
key = Console.ReadKey(true);
// Ignore any key out of range.
if (((int) key.Key) >= 65 && ((int) key.Key <= 90)) {
// Append the character to the password.
securePwd.AppendChar(key.KeyChar);
Console.Write("*");
}
// Exit if Enter key is pressed.
} while (key.Key != ConsoleKey.Enter);
Console.WriteLine();
try {
Process.Start("Notepad.exe", "MyUser", securePwd, "MYDOMAIN");
}
catch (Win32Exception e) {
Console.WriteLine(e.Message);
}
finally {
securePwd.Dispose();
}
}
}
Imports System.ComponentModel
Imports System.Diagnostics
Imports System.Security
Public Class Example
Public Shared Sub Main()
' Instantiate the secure string.
Dim securePwd As New SecureString()
Dim key As ConsoleKeyInfo
Console.Write("Enter password: ")
Do
key = Console.ReadKey(True)
' Ignore any key out of range
If CInt(key.Key) >= 65 And CInt(key.Key <= 90) Then
' Append the character to the password.
securePwd.AppendChar(key.KeyChar)
Console.Write("*")
End If
' Exit if Enter key is pressed.
Loop While key.Key <> ConsoleKey.Enter
Console.WriteLine()
Try
Process.Start("Notepad.exe", "MyUser", securePwd, "MYDOMAIN")
Catch e As Win32Exception
Console.WriteLine(e.Message)
Finally
securePwd.Dispose()
End Try
End Sub
End Class
備註
重要
不建議您將 類別用於 SecureString
新的開發。 如需詳細資訊,請參閱 不應在 GitHub 上使用 SecureString 。
SecureString 是提供安全性量值的字串類型。 它會嘗試避免將潛在的敏感性字串儲存在進程記憶體中做為純文字。 (如需限制,請參閱 SecureString 有多安全? 一節。) 實例的值 SecureString 會使用初始化實例時或修改值時基礎平臺所支援的機制自動保護。 您的應用程式可以轉譯不可變的實例,並藉由叫用 MakeReadOnly 方法來防止進一步修改。
實例的最大 SecureString 長度為 65,536 個字元。
重要
此型別代表 IDisposable 介面。 當您使用型別的實例完成時,應該直接或間接處置它。 若要直接處置型別,請呼叫其 try
/catch
區塊中的 Dispose 方法。 若要間接處置它,請使用語言建構函式,例如 using
(在 C# 中) 或 Using
(在 Visual Basic 中)。 如需詳細資訊,請參閱 IDisposable 介面文章中的<使用實作 IDisposable 的物件>一節。
COM 看不到類別 SecureString 及其成員。 如需詳細資訊,請參閱ComVisibleAttribute。
本節內容:
String 與 SecureString
SecureString 作業
SecureString 和 Interop
SecureString 有多安全?
字串與 SecureString
類別的實例既是不可變的 System.String ,也不再需要時,無法以程式設計方式排程進行垃圾收集;也就是說,實例在建立之後是唯讀的,而且無法預測實例何時會從電腦記憶體中刪除。 因為 System.String 實例是不可變的,所以似乎修改現有實例的作業實際上會建立要操作的複本。 因此,如果 String 物件包含機密資訊,例如密碼、信用卡號碼或個人資料,則因為您的應用程式無法從電腦記憶體中刪除資料,所以可能會顯示資訊的風險。
SecureString物件與 String 物件類似,因為它具有文字值。 不過,物件的值 SecureString 會釘選在記憶體中,可能會使用保護機制,例如基礎作業系統提供的加密,可以修改,直到您的應用程式將它標示為唯讀為止,而且可以透過 Dispose 呼叫 方法的應用程式或.NET Framework垃圾收集行程,從電腦記憶體中刪除。
如需 類別限制 SecureString 的討論,請參閱 SecureString 如何安全? 一節。
SecureString 作業
類別 SecureString 包含可讓您執行下列動作的成員:
具現化 SecureString 物件
您可以呼叫其無參數建構函式來具現化 SecureString 物件。
將字元新增至 SecureString 物件
您可以呼叫 物件 AppendChar 或 InsertAt 方法,一次將單一字元新增至 SecureString 物件。
重要
SecureString物件絕對不應該從 String 建構,因為敏感性資料已經受限於不可變 String 類別的記憶體持續性結果。 建構 SecureString 物件的最佳方式是來自一次字元 Unmanaged 來源,例如 Console.ReadKey 方法。
從 SecureString 物件中移除字元
您可以呼叫 SetAt 方法來取代個別字元、呼叫 RemoveAt 方法移除個別字元,或呼叫 Clear 方法移除 實例中的所有字元 SecureString 。
SecureString將物件設為唯讀
定義物件所代表的 SecureString 字串之後,您可以呼叫其 MakeReadOnly 方法,讓字串成為唯讀的。
取得物件的相關資訊 SecureString
類別 SecureString 只有兩個成員提供字串的相關資訊:其 Length 屬性,指出字串中 UTF16 編碼的程式碼單位數目,以及 IsReadOnly 指出實例是否為唯讀的 、 方法。
釋放配置給 實例的 SecureString 記憶體
因為 SecureString 會實作 IDisposable 介面,所以您可以呼叫 Dispose 方法來釋放其記憶體。
類別 SecureString 沒有檢查、比較或轉換 值 SecureString 的成員。 缺少這類成員反而有助於防止執行個體值被不慎或惡意公開。 使用 類別的適當成員 System.Runtime.InteropServices.Marshal ,例如 SecureStringToBSTR 方法,以操作 物件的值 SecureString 。
.NET Framework類別庫通常會以下列方式使用 SecureString 實例:
若要使用 ProcessStartInfo 結構或呼叫方法的多 Process.Start 載,將密碼資訊提供給進程,方法的類型為 SecureString 。
若要藉由呼叫 NetworkCredential 具有 型 SecureString 別參數的類別建構函式或使用 NetworkCredential.SecurePassword 屬性來提供網路密碼資訊。
若要藉由呼叫 SqlCredential.SqlCredential 建構函式或擷取 SqlCredential.Password 屬性值來提供驗證SQL Server密碼資訊。
將字串傳遞至 Unmanaged 程式碼。 如需詳細資訊,請參閱 SecureString 和 Interop 一節。
SecureString 和 Interop
因為作業系統並不直接支援 SecureString ,所以您必須將物件的值 SecureString 轉換為必要的字串類型,才能將字串傳遞至原生方法。 類別 Marshal 有五個執行此動作的方法:
Marshal.SecureStringToBSTR,可將字串值轉換成 SecureString COM 所辨識的二進位字串 (BSTR) 。
Marshal.SecureStringToCoTaskMemAnsi 和 Marshal.SecureStringToGlobalAllocAnsi ,會將 SecureString 字串值複製到 Unmanaged 記憶體中的 ANSI 字串。
Marshal.SecureStringToCoTaskMemUnicode 和 Marshal.SecureStringToGlobalAllocUnicode ,會將 SecureString 字串值複製到 Unmanaged 記憶體中的 Unicode 字串。
所有這些方法都會在 Unmanaged 記憶體中建立純文字字串。 開發人員必須負責在不再需要記憶體後立即清空並釋放該記憶體。 每個字串轉換和記憶體配置方法都有對應的方法,以零出並釋放配置的記憶體:
SecureString 有多安全?
正確建立時, SecureString 實例會提供比 更多的 String 資料保護。 從字元一次來源建立字串時, String 會在記憶體中建立多個中繼,而 SecureString 只會建立單一實例。 物件的垃圾收集 String 不具決定性。 此外,因為未釘選其記憶體,所以垃圾收集行程會在移動和壓縮記憶體時,建立額外的值複本 String 。 相反地,配置給 SecureString 物件的記憶體會釘選,而且可以呼叫 Dispose 方法來釋放該記憶體。
雖然儲存在 SecureString 實例中的資料比儲存在實例中的資料 String 更安全,但實例的安全性 SecureString 有顯著的限制。 它們包括:
平台
在 Windows 作業系統上,實例的內部字元陣列內容 SecureString 會加密。 不過,不論因為遺漏 API 或金鑰管理問題,加密都無法在所有平臺上使用。 由於此平臺相依性, SecureString 因此不會加密非 Windows 平臺上的內部儲存體。 這些平臺上會使用其他技術來提供額外的保護。
Duration
即使實作 SecureString 能夠利用加密,指派給實例的 SecureString 純文字可能會在各種時間公開:
因為 Windows 不會在作業系統層級提供安全字串實作,所以.NET Framework仍然需要將安全字串值轉換成其純文字標記法,才能使用它。
每當或 RemoveAt 之類的 AppendChar 方法修改安全字串的值時,都必須解密 (,也就是轉換回純文字) 、修改,然後再加密一次。
如果在 Interop 呼叫中使用安全字串,則必須轉換成 ANSI 字串、Unicode 字串或二進位字串, (BSTR) 。 如需詳細資訊,請參閱 SecureString 和 Interop 一節。
與 類別相比 String ,只會縮短實例值公開的時間間隔 SecureString 。
儲存體與使用量
一般而言,類別 SecureString 會定義字串值的儲存機制,這些值應該受到保護或保留機密。 不過,在.NET Framework本身之外,沒有使用機制支援 SecureString 。 這表示安全字串必須轉換成可用的表單 (通常是可辨識其目標的純文字表單) ,而且解密和轉換必須在使用者空間中發生。
整體而言, SecureString 比 String 起會限制敏感性字串資料的暴露,所以更安全。 不過,這些字串仍可能會公開給任何可存取原始記憶體的進程或作業,例如在主機電腦上執行的惡意進程、進程傾印或使用者可檢視的交換檔案。 建議的替代方式是使用不透明控制碼來保護儲存在進程外部的認證,而不是使用 SecureString 來保護密碼。
建構函式
SecureString() |
初始化 SecureString 類別的新執行個體。 |
SecureString(Char*, Int32) |
從 Char 物件的子陣列,初始化 SecureString 類別的新執行個體。 這個建構函式不符合 CLS 標準。 符合 CLS 標準的替代項目為 SecureString()。 |
屬性
Length |
取得目前安全字串中的字元數。 |
方法
AppendChar(Char) |
將字元附加至目前安全字串的結尾。 |
Clear() |
刪除目前安全字串的值。 |
Copy() |
建立目前安全字串的複本。 |
Dispose() |
釋放由 SecureString 物件使用的所有資源。 |
Equals(Object) |
判斷指定的物件是否等於目前的物件。 (繼承來源 Object) |
GetHashCode() |
做為預設雜湊函式。 (繼承來源 Object) |
GetType() |
取得目前執行個體的 Type。 (繼承來源 Object) |
InsertAt(Int32, Char) |
將這個安全字串中的字元插入指定索引位置。 |
IsReadOnly() |
指示這個安全字串是否標示為唯讀。 |
MakeReadOnly() |
使這個安全字串的文字值成為唯讀。 |
MemberwiseClone() |
建立目前 Object 的淺層複製。 (繼承來源 Object) |
RemoveAt(Int32) |
從這個安全字串移除位在指定索引位置的字元。 |
SetAt(Int32, Char) |
使用另一個字元,取代位在指定索引位置的現有字元。 |
ToString() |
傳回代表目前物件的字串。 (繼承來源 Object) |