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"部分。)初始化实例或修改值时,将使用基础平台支持的机制自动保护 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. 您的应用程序可以通过调用 MakeReadOnly 方法,使实例不可变,并阻止进一步的修改。Your 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 类的限制的讨论,请参阅 how of 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.

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

重要

永远不应从 String构造 SecureString 对象,因为敏感数据已受到不可变 String 类的内存持久性后果的影响。A 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.

删除 SecureString 对象中的字符Remove characters from a SecureString object
您可以通过调用 SetAt 方法来替换单个字符、通过调用 RemoveAt 方法删除单个字符或通过调用 Clear 方法删除 SecureString 实例中的所有字符。You 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.

获取有关 SecureString 对象的信息Get 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.

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

SecureString 类没有用于检查、比较或转换 SecureString的值的成员。The 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.Marshal 类的适当成员(如 SecureStringToBSTR 方法)操作 SecureString 对象的值。Use 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 实例提供的数据保护比 String更多。When 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 对象的内存将固定,并且可以通过调用 Dispose 方法来释放内存。In contrast, the memory allocated to a SecureString object is pinned, and that memory can be freed by calling the Dispose method.

尽管 SecureString 实例中存储的数据比 String 实例中存储的数据更安全,但对 SecureString 实例的安全有很大的限制。Although 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:

PlatformPlatform
在 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.

  • 每当安全字符串的值由 AppendCharRemoveAt这样的方法修改时,必须对其进行解密(即转换回纯文本),修改后再次加密。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.

String 类相比,只需缩短 SecureString 实例的值的显示时间间隔。The 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()

返回一个表示当前对象的 string。Returns a string that represents the current object.

(继承自 Object)

适用于

另请参阅