SecureString 類別

定義

代表應該將文字保密,例如於不再使用時將它從電腦記憶體刪除。 此類別無法獲得繼承。

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 物件
您可以呼叫 物件 AppendCharInsertAt 方法,一次將單一字元新增至 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 實例:

回到頁首

SecureString 和 Interop

因為作業系統並不直接支援 SecureString ,所以您必須將物件的值 SecureString 轉換為必要的字串類型,才能將字串傳遞至原生方法。 類別 Marshal 有五個執行此動作的方法:

所有這些方法都會在 Unmanaged 記憶體中建立純文字字串。 開發人員必須負責在不再需要記憶體後立即清空並釋放該記憶體。 每個字串轉換和記憶體配置方法都有對應的方法,以零出並釋放配置的記憶體:

配置和轉換方法 零和可用方法
Marshal.SecureStringToBSTR Marshal.ZeroFreeBSTR
Marshal.SecureStringToCoTaskMemAnsi Marshal.ZeroFreeCoTaskMemAnsi
Marshal.SecureStringToCoTaskMemUnicode Marshal.ZeroFreeCoTaskMemUnicode
Marshal.SecureStringToGlobalAllocAnsi Marshal.ZeroFreeGlobalAllocAnsi
Marshal.SecureStringToGlobalAllocUnicode Marshal.ZeroFreeGlobalAllocUnicode

回到頁首

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 。 這表示安全字串必須轉換成可用的表單 (通常是可辨識其目標的純文字表單) ,而且解密和轉換必須在使用者空間中發生。

整體而言, SecureStringString 起會限制敏感性字串資料的暴露,所以更安全。 不過,這些字串仍可能會公開給任何可存取原始記憶體的進程或作業,例如在主機電腦上執行的惡意進程、進程傾印或使用者可檢視的交換檔案。 建議的替代方式是使用不透明控制碼來保護儲存在進程外部的認證,而不是使用 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)

適用於

另請參閱