SecureString 类

定义

表示应保密的文本,例如在不再需要时将其从计算机内存中删除。Represents text that should be kept confidential, such as by deleting it from computer memory when no longer needed. 此类不能被继承。This class cannot be inherited.

public ref class SecureString sealed : IDisposable
public sealed class SecureString : IDisposable
type SecureString = class
    interface IDisposable
Public NotInheritable Class SecureString
Implements IDisposable
继承
SecureString
实现

示例

下面的示例演示如何使用 SecureString 保护用户的密码,以将其用作凭据以启动新进程。The following example demonstrates how to use a SecureString to secure a user's password for use as a credential to start a new process.

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 类进行新的开发。We don't recommend that you use the SecureString class for new development. 有关详细信息,请参阅 GitHub 上的 SecureString 不应使用For more information, see SecureString shouldn't be used on GitHub.

SecureString 是提供安全度量值的字符串类型。SecureString is a string type that provides a measure of security. 它尝试避免以纯文本形式在进程内存中存储可能敏感的字符串。It tries to avoid storing potentially sensitive strings in process memory as plain text. (的限制,请参阅 " 安全设置的安全级别 " 一节。 ) 实例的值是在 SecureString 初始化实例或修改该值时使用基础平台支持的机制自动保护的。(For limitations, however, see the How secure is SecureString? section.) The value of an instance of SecureString is automatically protected using a mechanism supported by the underlying platform when the instance is initialized or when the value is modified. 您的应用程序可以通过调用方法来使实例不可变,并防止进一步的修改 MakeReadOnlyYour application can render the instance immutable and prevent further modification by invoking the MakeReadOnly method.

实例的最大长度 SecureString 为65536个字符。The maximum length of a SecureString instance is 65,536 characters.

重要

此类型实现 IDisposable 接口。This type implements the IDisposable interface. 使用完该类型的实例后,应直接或间接释放该实例。When you have finished using an instance of the type, you should dispose of it either directly or indirectly. 若要直接释放类型,请在 try/catch 块中调用其 Dispose 方法。To dispose of the type directly, call its Dispose method in a try/catch block. 若要间接释放类型,请使用 using(在 C# 中)或 Using(在 Visual Basic 中)等语言构造。To dispose of it indirectly, use a language construct such as using (in C#) or Using (in Visual Basic). 有关详细信息,请参阅 IDisposable 接口主题中的“使用实现 IDisposable 的对象”一节。For more information, see the "Using an Object that Implements IDisposable" section in the IDisposable interface topic.

SecureString类及其成员对 COM 不可见。The SecureString class and its members are not visible to COM. 有关详细信息,请参阅 ComVisibleAttributeFor more information, see ComVisibleAttribute.

本部分内容:In this section:

String 与 SecureString String vs. SecureString
SecureString 操作 SecureString operations
SecureString 和互操作 SecureString and interop
SecureString 的安全程度如何?How secure is SecureString?

String 与 SecureStringString versus SecureString

类的实例 System.String 是不可变的,并且在不再需要时不能以编程方式计划进行垃圾回收; 也就是说,实例在创建后是只读的,并且不能预测将从计算机内存中删除该实例的时间。An instance of the System.String class is both immutable and, when no longer needed, cannot be programmatically scheduled for garbage collection; that is, the instance is read-only after it is created, and it is not possible to predict when the instance will be deleted from computer memory. 因为 System.String 实例是不可变的,所以看起来修改现有实例的操作实际上会创建它要操作的副本。Because System.String instances are immutable, operations that appear to modify an existing instance actually create a copy of it to manipulate. 因此,如果 String 对象包含敏感信息(如密码、信用卡号或个人数据),则在使用该信息时可能会出现一种风险,因为应用程序无法从计算机内存中删除数据。Consequently, if a String object contains sensitive information such as a password, credit card number, or personal data, there is a risk the information could be revealed after it is used because your application cannot delete the data from computer memory.

SecureString对象类似于 String 对象,因为它具有一个文本值。A SecureString object is similar to a String object in that it has a text value. 但是,对象的值 SecureString 固定在内存中,可能会使用基础操作系统提供的保护机制(如加密),直到应用程序将其标记为只读,并且可以通过调用方法的应用程序 Dispose 或 .NET Framework 垃圾回收器将其从计算机内存中删除。However, the value of a SecureString object is pinned in memory, may use a protection mechanism, such as encryption, provided by the underlying operating system, can be modified until your application marks it as read-only, and can be deleted from computer memory either by your application calling the Dispose method or by the .NET Framework garbage collector.

有关类的限制的讨论 SecureString ,请参阅 " 安全设置 SecureString" 部分。For a discussion of the limitations of the SecureString class, see the How secure is SecureString? section.

返回页首Back to top

SecureString 操作SecureString operations

SecureString类包括允许你执行以下操作的成员:The SecureString class includes members that allow you to do the following:

实例化 SecureString 对象Instantiate a SecureString object
SecureString通过调用对象的无参数构造函数来实例化对象。You instantiate a SecureString object by calling its parameterless constructor.

向对象添加字符 SecureStringAdd characters to a SecureString object
可以 SecureString 通过调用对象的 AppendChar 或方法,一次将一个字符添加到对象 InsertAtYou can add a single character at a time to a SecureString object by calling its AppendChar or InsertAt method.

重要

SecureString永远不应从构造对象 String ,因为敏感数据已受到不可变类的内存持久性后果的限制 StringA SecureString object should never be constructed from a String, because the sensitive data is already subject to the memory persistence consequences of the immutable String class. 构造对象的最佳方式 SecureString 是从非实时的非托管源(例如 Console.ReadKey 方法)。The best way to construct a SecureString object is from a character-at-a-time unmanaged source, such as the Console.ReadKey method.

从对象中删除字符 SecureStringRemove characters from a SecureString object
可以通过调用方法来替换单个字符 SetAt 、通过调用方法删除单个字符 RemoveAtSecureString 通过调用方法从实例中移除所有字符 ClearYou can replace an individual character by calling the SetAt method, remove an individual character by calling the RemoveAt method, or remove all characters from the SecureString instance by calling the Clear method.

使 SecureString 对象成为只读Make the SecureString object read-only
定义对象表示的字符串后 SecureString ,调用其 MakeReadOnly 方法,使字符串成为只读的。Once you have defined the string that the SecureString object represents, you call its MakeReadOnly method to make the string read-only.

获取有关对象的信息 SecureStringGet information about the SecureString object
SecureString类只包含两个提供有关字符串的信息的成员:其 Length 属性,指示字符串中 UTF16 编码的代码单元的数目; 以及 IsReadOnly 指示该实例是否为只读的方法。The SecureString class has only two members that provide information about the string: its Length property, which indicates the number of UTF16-encoded code units in the string; and the IsReadOnly, method, which indicates whether the instance is read-only.

释放分配给实例的内存 SecureStringRelease the memory allocated to the SecureString instance
由于 SecureString 实现 IDisposable 接口,因此可以通过调用方法释放其内存 DisposeBecause SecureString implements the IDisposable interface, you release its memory by calling the Dispose method.

SecureString类没有任何成员用于检查、比较或转换的值 SecureStringThe SecureString class has no members that inspect, compare, or convert the value of a SecureString. 由于缺少这类成员,因此有助于保护实例的值不被意外或恶意公开。The absence of such members helps protect the value of the instance from accidental or malicious exposure. 使用类的适当成员( System.Runtime.InteropServices.MarshalSecureStringToBSTR 方法)来操作对象的值 SecureStringUse appropriate members of the System.Runtime.InteropServices.Marshal class, such as the SecureStringToBSTR method, to manipulate the value of a SecureString object.

.NET Framework 类库通常 SecureString 以下列方式使用实例:The .NET Framework Class Library commonly uses SecureString instances in the following ways:

返回页首Back to top

SecureString 和互操作SecureString and interop

由于操作系统不直接支持 SecureString ,因此必须先将对象的值转换 SecureString 为所需的字符串类型,然后才能将该字符串传递给本机方法。Because the operating system does not directly support SecureString, you must convert the value of the SecureString object to the required string type before passing the string to a native method. Marshal类具有五种执行此操作的方法:The Marshal class has five methods that do this:

其中每种方法在非托管内存中创建一个明文字符串。Each of these methods creates a clear-text string in unmanaged memory. 开发人员负责在不再需要该内存时将其从零开始,并将其释放。It is the responsibility of the developer to zero out and free that memory as soon as it is no longer needed. 每个字符串转换和内存分配方法都有一个对应的方法,以使分配的内存为零并释放已分配的内存:Each of the string conversion and memory allocation methods has a corresponding method to zero out and free the allocated memory:

分配和转换方法Allocation and conversion method 零和免费方法Zero and free method
Marshal.SecureStringToBSTR Marshal.ZeroFreeBSTR
Marshal.SecureStringToCoTaskMemAnsi Marshal.ZeroFreeCoTaskMemAnsi
Marshal.SecureStringToCoTaskMemUnicode Marshal.ZeroFreeCoTaskMemUnicode
Marshal.SecureStringToGlobalAllocAnsi Marshal.ZeroFreeGlobalAllocAnsi
Marshal.SecureStringToCoTaskMemUnicode Marshal.ZeroFreeGlobalAllocUnicode

返回页首Back to top

SecureString 的安全程度如何?How secure is SecureString?

正确创建后, SecureString 实例提供的数据保护比更多 StringWhen created properly, a SecureString instance provides more data protection than a String. 当从一个字符的时间源创建字符串时,将 String 在内存中创建多个中间,而 SecureString 只创建一个实例。When creating a string from a character-at-a-time source, String creates multiple intermediate in memory, whereas SecureString creates just a single instance. 对象的垃圾回收 String 是不确定的。Garbage collection of String objects is non-deterministic. 此外,由于未固定其内存,垃圾回收器将 String 在移动和压缩内存时创建值的其他副本。In addition, because its memory is not pinned, the garbage collector will make additional copies of String values when moving and compacting memory. 相反,分配给对象的内存 SecureString 将固定,并且可以通过调用方法来释放内存 DisposeIn contrast, the memory allocated to a SecureString object is pinned, and that memory can be freed by calling the Dispose method.

虽然实例中存储的数据 SecureString 比实例中存储的数据更安全 String ,但对实例的安全有很大的限制 SecureStringAlthough data stored in a SecureString instance is more secure than data stored in a String instance, there are significant limitations on how secure a SecureString instance is. 这些方法包括:These include:

平台Platform
在 Windows 操作系统上, SecureString 实例的内部字符数组的内容已加密。On the Windows operating system, the contents of a SecureString instance's internal character array are encrypted. 但是,无论是否缺少 Api 或密钥管理问题,加密在所有平台上都不可用。However, whether because of missing APIs or key management issues, encryption is not available on all platforms. 由于此平台依赖项,不 SecureString 会对非 Windows 平台上的内部存储进行加密。Because of this platform dependency, SecureString does not encrypt the internal storage on non-Windows platform. 在这些平台上使用其他技术来提供附加保护。Other techniques are used on those platforms to provide additional protection.

持续时间Duration
即使 SecureString 实现能够利用加密,分配给实例的纯文本 SecureString 也可能会在不同的时间公开:Even if the SecureString implementation is able to take advantage of encryption, the plain text assigned to the SecureString instance may be exposed at various times:

  • 由于 Windows 不在操作系统级别提供安全字符串实现,因此 .NET Framework 仍必须将安全字符串值转换为纯文本表示形式才能使用。Because Windows doesn't offer a secure string implementation at the operating system level, the .NET Framework still has to convert the secure string value to its plain text representation in order to use it.

  • 每当使用或等方法修改安全字符串的值时,都 AppendChar RemoveAt 必须将其解密 (也就是说,转换回纯文本) ,修改后再次加密。Whenever the value of the secure string is modified by methods such as AppendChar or RemoveAt, it must be decrypted (that is, converted back to plain text), modified, and then encrypted again.

  • 如果在互操作调用中使用安全字符串,则必须将其转换为 ANSI 字符串、Unicode 字符串或 (BSTR) 的二进制字符串。If the secure string is used in an interop call, it must be converted to an ANSI string, a Unicode string, or a binary string (BSTR). 有关详细信息,请参阅 SecureString and 互操作 部分。For more information, see the SecureString and interop section.

SecureString与类相比,实例的值公开的时间间隔只需缩短 StringThe time interval for which the SecureString instance's value is exposed is merely shortened in comparison to the String class.

存储与使用情况Storage versus usage
更常见的情况是, SecureString 类为应受到保护或保密的字符串值定义存储机制。More generally, the SecureString class defines a storage mechanism for string values that should be protected or kept confidential. 但是,在 .NET Framework 之外,不支持使用机制 SecureStringHowever, outside of the .NET Framework itself, no usage mechanism supports SecureString. 这意味着,必须将安全字符串转换为可用形式 (通常为明文形式) 可以被其目标识别,并且必须在用户空间中进行解密和转换。This means that the secure string must be converted to a usable form (typically a clear text form) that can be recognized by its target, and that decryption and conversion must occur in user space.

总体而言, SecureStringString 它限制敏感字符串数据的公开更安全。Overall, SecureString is more secure than String because it limits the exposure of sensitive string data. 但是,这些字符串可能仍会公开给有权访问原始内存的任何进程或操作,例如,在主计算机上运行的恶意进程、进程转储或用户可查看的交换文件。However, those strings may still be exposed to any process or operation that has access to raw memory, such as a malicious process running on the host computer, a process dump, or a user-viewable swap file. SecureString建议的替代方法是对存储在进程外部的凭据使用不透明的句柄,而不是使用来保护密码。Instead of using SecureString to protect passwords, the recommended alternative is to use an opaque handle to credentials that are stored outside of the process.

返回页首Back to top

构造函数

SecureString()

初始化 SecureString 类的新实例。Initializes a new instance of the SecureString class.

SecureString(Char*, Int32)

Char 对象的子数组初始化 SecureString 类的新实例。Initializes a new instance of the SecureString class from a subarray of Char objects.

此构造函数不符合 CLS。This constructor is not CLS-compliant. 符合 CLS 的替代方法是 SecureString()The CLS-compliant alternative is SecureString().

属性

Length

获取当前安全字符串中的字符数。Gets the number of characters in the current secure string.

方法

AppendChar(Char)

在当前安全字符串的末尾追加一个字符。Appends a character to the end of the current secure string.

Clear()

删除当前安全字符串的值。Deletes the value of the current secure string.

Copy()

创建当前安全字符串的副本。Creates a copy of the current secure string.

Dispose()

释放由当前 SecureString 对象使用的所有资源。Releases all resources used by the current SecureString object.

Equals(Object)

确定指定对象是否等于当前对象。Determines whether the specified object is equal to the current object.

(继承自 Object)
GetHashCode()

作为默认哈希函数。Serves as the default hash function.

(继承自 Object)
GetType()

获取当前实例的 TypeGets the Type of the current instance.

(继承自 Object)
InsertAt(Int32, Char)

在此安全字符串中的指定索引位置插入一个字符。Inserts a character in this secure string at the specified index position.

IsReadOnly()

指示此安全字符串是否标记为只读。Indicates whether this secure string is marked read-only.

MakeReadOnly()

将此安全字符串的文本值设置为只读。Makes the text value of this secure string read-only.

MemberwiseClone()

创建当前 Object 的浅表副本。Creates a shallow copy of the current Object.

(继承自 Object)
RemoveAt(Int32)

从此安全字符串中的指定索引位置移除字符。Removes the character at the specified index position from this secure string.

SetAt(Int32, Char)

将指定索引位置上的现有字符替换为其他字符。Replaces the existing character at the specified index position with another character.

ToString()

返回表示当前对象的字符串。Returns a string that represents the current object.

(继承自 Object)

适用于

另请参阅