Rfc2898DeriveBytes 类 
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
通过使用基于 HMACSHA1 的伪随机数生成器,实现基于密码的密钥派生功能 (PBKDF2)。
public ref class Rfc2898DeriveBytes : System::Security::Cryptography::DeriveBytes
	[System.Runtime.Versioning.UnsupportedOSPlatform("browser")]
public class Rfc2898DeriveBytes : System.Security.Cryptography.DeriveBytes
	public class Rfc2898DeriveBytes : System.Security.Cryptography.DeriveBytes
	[System.Runtime.InteropServices.ComVisible(true)]
public class Rfc2898DeriveBytes : System.Security.Cryptography.DeriveBytes
	[<System.Runtime.Versioning.UnsupportedOSPlatform("browser")>]
type Rfc2898DeriveBytes = class
    inherit DeriveBytes
	type Rfc2898DeriveBytes = class
    inherit DeriveBytes
	[<System.Runtime.InteropServices.ComVisible(true)>]
type Rfc2898DeriveBytes = class
    inherit DeriveBytes
	Public Class Rfc2898DeriveBytes
Inherits DeriveBytes
		- 继承
 
- 属性
 
示例
下面的代码示例使用 Rfc2898DeriveBytes 类为 Aes 类创建两个相同的键。 然后,它使用密钥加密和解密某些数据。
using namespace System;
using namespace System::IO;
using namespace System::Text;
using namespace System::Security::Cryptography;
// Generate a key k1 with password pwd1 and salt salt1.
// Generate a key k2 with password pwd1 and salt salt1.
// Encrypt data1 with key k1 using symmetric encryption, creating edata1.
// Decrypt edata1 with key k2 using symmetric decryption, creating data2.
// data2 should equal data1.
int main()
{
   array<String^>^passwordargs = Environment::GetCommandLineArgs();
   String^ usageText = "Usage: RFC2898 <password>\nYou must specify the password for encryption.\n";
   //If no file name is specified, write usage text.
   if ( passwordargs->Length == 1 )
   {
      Console::WriteLine( usageText );
   }
   else
   {
      String^ pwd1 = passwordargs[ 1 ];
      
      array<Byte>^salt1 = gcnew array<Byte>(8);
      RNGCryptoServiceProvider ^ rngCsp = gcnew RNGCryptoServiceProvider();
         rngCsp->GetBytes(salt1);
      //data1 can be a string or contents of a file.
      String^ data1 = "Some test data";
      //The default iteration count is 1000 so the two methods use the same iteration count.
      int myIterations = 1000;
      try
      {
         Rfc2898DeriveBytes ^ k1 = gcnew Rfc2898DeriveBytes( pwd1,salt1,myIterations );
         Rfc2898DeriveBytes ^ k2 = gcnew Rfc2898DeriveBytes( pwd1,salt1 );
         // Encrypt the data.
         Aes^ encAlg = Aes::Create();
         encAlg->Key = k1->GetBytes( 16 );
         MemoryStream^ encryptionStream = gcnew MemoryStream;
         CryptoStream^ encrypt = gcnew CryptoStream( encryptionStream,encAlg->CreateEncryptor(),CryptoStreamMode::Write );
         array<Byte>^utfD1 = (gcnew System::Text::UTF8Encoding( false ))->GetBytes( data1 );
         encrypt->Write( utfD1, 0, utfD1->Length );
         encrypt->FlushFinalBlock();
         encrypt->Close();
         array<Byte>^edata1 = encryptionStream->ToArray();
         k1->Reset();
         // Try to decrypt, thus showing it can be round-tripped.
         Aes^ decAlg = Aes::Create();
         decAlg->Key = k2->GetBytes( 16 );
         decAlg->IV = encAlg->IV;
         MemoryStream^ decryptionStreamBacking = gcnew MemoryStream;
         CryptoStream^ decrypt = gcnew CryptoStream( decryptionStreamBacking,decAlg->CreateDecryptor(),CryptoStreamMode::Write );
         decrypt->Write( edata1, 0, edata1->Length );
         decrypt->Flush();
         decrypt->Close();
         k2->Reset();
         String^ data2 = (gcnew UTF8Encoding( false ))->GetString( decryptionStreamBacking->ToArray() );
         if (  !data1->Equals( data2 ) )
         {
            Console::WriteLine( "Error: The two values are not equal." );
         }
         else
         {
            Console::WriteLine( "The two values are equal." );
            Console::WriteLine( "k1 iterations: {0}", k1->IterationCount );
            Console::WriteLine( "k2 iterations: {0}", k2->IterationCount );
         }
      }
      catch ( Exception^ e ) 
      {
         Console::WriteLine( "Error: ", e );
      }
   }
}
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
public class rfc2898test
{
    // Generate a key k1 with password pwd1 and salt salt1.
    // Generate a key k2 with password pwd1 and salt salt1.
    // Encrypt data1 with key k1 using symmetric encryption, creating edata1.
    // Decrypt edata1 with key k2 using symmetric decryption, creating data2.
    // data2 should equal data1.
    private const string usageText = "Usage: RFC2898 <password>\nYou must specify the password for encryption.\n";
    public static void Main(string[] passwordargs)
    {
        //If no file name is specified, write usage text.
        if (passwordargs.Length == 0)
        {
            Console.WriteLine(usageText);
        }
        else
        {
            string pwd1 = passwordargs[0];
            // Create a byte array to hold the random value.
            byte[] salt1 = new byte[8];
            using (RNGCryptoServiceProvider rngCsp = new
RNGCryptoServiceProvider())
            {
                // Fill the array with a random value.
                rngCsp.GetBytes(salt1);
            }
            //data1 can be a string or contents of a file.
            string data1 = "Some test data";
            //The default iteration count is 1000 so the two methods use the same iteration count.
            int myIterations = 1000;
            try
            {
                Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(pwd1, salt1,
myIterations);
                Rfc2898DeriveBytes k2 = new Rfc2898DeriveBytes(pwd1, salt1);
                // Encrypt the data.
                Aes encAlg = Aes.Create();
                encAlg.Key = k1.GetBytes(16);
                MemoryStream encryptionStream = new MemoryStream();
                CryptoStream encrypt = new CryptoStream(encryptionStream,
encAlg.CreateEncryptor(), CryptoStreamMode.Write);
                byte[] utfD1 = new System.Text.UTF8Encoding(false).GetBytes(
data1);
                encrypt.Write(utfD1, 0, utfD1.Length);
                encrypt.FlushFinalBlock();
                encrypt.Close();
                byte[] edata1 = encryptionStream.ToArray();
                k1.Reset();
                // Try to decrypt, thus showing it can be round-tripped.
                Aes decAlg = Aes.Create();
                decAlg.Key = k2.GetBytes(16);
                decAlg.IV = encAlg.IV;
                MemoryStream decryptionStreamBacking = new MemoryStream();
                CryptoStream decrypt = new CryptoStream(
decryptionStreamBacking, decAlg.CreateDecryptor(), CryptoStreamMode.Write);
                decrypt.Write(edata1, 0, edata1.Length);
                decrypt.Flush();
                decrypt.Close();
                k2.Reset();
                string data2 = new UTF8Encoding(false).GetString(
decryptionStreamBacking.ToArray());
                if (!data1.Equals(data2))
                {
                    Console.WriteLine("Error: The two values are not equal.");
                }
                else
                {
                    Console.WriteLine("The two values are equal.");
                    Console.WriteLine("k1 iterations: {0}", k1.IterationCount);
                    Console.WriteLine("k2 iterations: {0}", k2.IterationCount);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: {0}", e);
            }
        }
    }
}
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography
Public Class rfc2898test
    ' Generate a key k1 with password pwd1 and salt salt1.
    ' Generate a key k2 with password pwd1 and salt salt1.
    ' Encrypt data1 with key k1 using symmetric encryption, creating edata1.
    ' Decrypt edata1 with key k2 using symmetric decryption, creating data2.
    ' data2 should equal data1.
    Private Const usageText As String = "Usage: RFC2898 <password>" + vbLf + "You must specify the password for encryption." + vbLf
    Public Shared Sub Main(ByVal passwordargs() As String)
        'If no file name is specified, write usage text.
        If passwordargs.Length = 0 Then
            Console.WriteLine(usageText)
        Else
            Dim pwd1 As String = passwordargs(0)
            Dim salt1(8) As Byte
            Using rngCsp As New RNGCryptoServiceProvider()
                rngCsp.GetBytes(salt1)
            End Using
            'data1 can be a string or contents of a file.
            Dim data1 As String = "Some test data"
            'The default iteration count is 1000 so the two methods use the same iteration count.
            Dim myIterations As Integer = 1000
            Try
                Dim k1 As New Rfc2898DeriveBytes(pwd1, salt1, myIterations)
                Dim k2 As New Rfc2898DeriveBytes(pwd1, salt1)
                ' Encrypt the data.
                Dim encAlg As Aes = Aes.Create()
                encAlg.Key = k1.GetBytes(16)
                Dim encryptionStream As New MemoryStream()
                Dim encrypt As New CryptoStream(encryptionStream, encAlg.CreateEncryptor(), CryptoStreamMode.Write)
                Dim utfD1 As Byte() = New System.Text.UTF8Encoding(False).GetBytes(data1)
                encrypt.Write(utfD1, 0, utfD1.Length)
                encrypt.FlushFinalBlock()
                encrypt.Close()
                Dim edata1 As Byte() = encryptionStream.ToArray()
                k1.Reset()
                ' Try to decrypt, thus showing it can be round-tripped.
                Dim decAlg As Aes = Aes.Create()
                decAlg.Key = k2.GetBytes(16)
                decAlg.IV = encAlg.IV
                Dim decryptionStreamBacking As New MemoryStream()
                Dim decrypt As New CryptoStream(decryptionStreamBacking, decAlg.CreateDecryptor(), CryptoStreamMode.Write)
                decrypt.Write(edata1, 0, edata1.Length)
                decrypt.Flush()
                decrypt.Close()
                k2.Reset()
                Dim data2 As String = New UTF8Encoding(False).GetString(decryptionStreamBacking.ToArray())
                If Not data1.Equals(data2) Then
                    Console.WriteLine("Error: The two values are not equal.")
                Else
                    Console.WriteLine("The two values are equal.")
                    Console.WriteLine("k1 iterations: {0}", k1.IterationCount)
                    Console.WriteLine("k2 iterations: {0}", k2.IterationCount)
                End If
            Catch e As Exception
                Console.WriteLine("Error: ", e)
            End Try
        End If
    End Sub
End Class
	注解
Rfc2898DeriveBytes 采用密码、盐和迭代计数,然后通过调用 GetBytes 方法生成密钥。
RFC 2898 包括用于从密码和 salt 创建密钥和初始化向量 (IV) 的方法。 可以使用 PBKDF2(一种基于密码的密钥派生函数)通过伪随机函数派生密钥,该函数允许生成几乎无限长度的密钥。 类 Rfc2898DeriveBytes 可用于从基键和其他参数生成派生密钥。 在基于密码的密钥派生函数中,基键是密码,其他参数是盐值和迭代计数。
有关 PBKDF2 的详细信息,请参阅 RFC 2898,标题为“PKCS #5:Password-Based 加密规范版本 2.0”。 有关完整的详细信息,请参阅第 5.2 节“PBKDF2”。
重要
切勿在源代码中对密码进行硬编码。 可以使用 Ildasm.exe (IL 反汇编程序) 从程序集中检索硬编码密码,或者只需在文本编辑器(如 Notepad.exe)中打开程序集即可。
构造函数
| Rfc2898DeriveBytes(Byte[], Byte[], Int32) | 
			 
				已过时.
			 
		通过使用密码、salt 值和迭代次数派生密钥,初始化 Rfc2898DeriveBytes 类的新实例。  | 
        	
| Rfc2898DeriveBytes(Byte[], Byte[], Int32, HashAlgorithmName) | 
		 初始化 Rfc2898DeriveBytes 类的新实例,该实例使用指定的密码、salt、迭代数和哈希算法名称来派生密钥。  | 
        	
| Rfc2898DeriveBytes(String, Byte[]) | 
			 
				已过时.
			 
		通过使用密码和 salt 值派生密钥,初始化 Rfc2898DeriveBytes 类的新实例。  | 
        	
| Rfc2898DeriveBytes(String, Byte[], Int32) | 
			 
				已过时.
			 
		通过使用密码、salt 值和迭代次数派生密钥,初始化 Rfc2898DeriveBytes 类的新实例。  | 
        	
| Rfc2898DeriveBytes(String, Byte[], Int32, HashAlgorithmName) | 
		 初始化 Rfc2898DeriveBytes 类的新实例,该实例使用指定的密码、salt、迭代数和哈希算法名称来派生密钥。  | 
        	
| Rfc2898DeriveBytes(String, Int32) | 
			 
				已过时.
			 
		通过使用密码和 salt 大小派生密钥,初始化 Rfc2898DeriveBytes 类的新实例。  | 
        	
| Rfc2898DeriveBytes(String, Int32, Int32) | 
			 
				已过时.
			 
		通过使用密码、salt 值和迭代次数派生密钥,初始化 Rfc2898DeriveBytes 类的新实例。  | 
        	
| Rfc2898DeriveBytes(String, Int32, Int32, HashAlgorithmName) | 
		 初始化 Rfc2898DeriveBytes 类的新实例,该实例使用指定的密码、salt 大小、迭代数和哈希算法名称来派生密钥。  | 
        	
属性
| HashAlgorithm | 
		 获取用于字节派生的哈希算法。  | 
        	
| IterationCount | 
		 获取或设置操作的迭代数。  | 
        	
| Salt | 
		 获取或设置操作的密钥 salt 值。  |