Rfc2898DeriveBytes 類別

定義

依據 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
屬性

範例

下列程式碼範例會 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 會採用密碼、salt 和反復專案計數,然後透過呼叫 GetBytes 方法來產生金鑰。

RFC 2898 包含從密碼和 salt 建立金鑰和初始化向量的方法, (IV) 。 您可以使用 PBKDF2 作為密碼型金鑰衍生函式,使用虛擬隨機函式來衍生金鑰,以允許產生幾乎無限制長度的金鑰。 類別 Rfc2898DeriveBytes 可用來從基底索引鍵和其他參數產生衍生金鑰。 在密碼型金鑰衍生函式中,基底金鑰是密碼,而其他參數則是 salt 值和反復專案計數。

如需 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 值。

方法

CryptDeriveKey(String, String, Int32, Byte[])
已淘汰.

Rfc2898DeriveBytes 物件衍生密碼編譯金鑰。

Dispose()

在衍生類別中覆寫時,將目前 DeriveBytes 類別的執行個體所使用的所有資源全部釋出。

(繼承來源 DeriveBytes)
Dispose(Boolean)

釋放 Rfc2898DeriveBytes 類別所使用的 Unmanaged 資源,並選擇性地釋放 Managed 資源。

Dispose(Boolean)

在衍生類別中覆寫時,釋出 DeriveBytes 類別使用的 Unmanaged 資源,並選擇性釋出 Managed 資源。

(繼承來源 DeriveBytes)
Equals(Object)

判斷指定的物件是否等於目前的物件。

(繼承來源 Object)
GetBytes(Int32)

傳回這個物件的似隨機金鑰。

GetHashCode()

做為預設雜湊函式。

(繼承來源 Object)
GetType()

取得目前執行個體的 Type

(繼承來源 Object)
MemberwiseClone()

建立目前 Object 的淺層複製。

(繼承來源 Object)
Pbkdf2(Byte[], Byte[], Int32, HashAlgorithmName, Int32)

從密碼位元組建立 PBKDF2 衍生的金鑰。

Pbkdf2(ReadOnlySpan<Byte>, ReadOnlySpan<Byte>, Int32, HashAlgorithmName, Int32)

從密碼位元組建立 PBKDF2 衍生的金鑰。

Pbkdf2(ReadOnlySpan<Byte>, ReadOnlySpan<Byte>, Span<Byte>, Int32, HashAlgorithmName)

使用 PBKDF2 衍生金鑰填滿緩衝區。

Pbkdf2(ReadOnlySpan<Char>, ReadOnlySpan<Byte>, Int32, HashAlgorithmName, Int32)

從密碼建立 PBKDF2 衍生金鑰。

Pbkdf2(ReadOnlySpan<Char>, ReadOnlySpan<Byte>, Span<Byte>, Int32, HashAlgorithmName)

使用 PBKDF2 衍生金鑰填滿緩衝區。

Pbkdf2(String, Byte[], Int32, HashAlgorithmName, Int32)

從密碼建立 PBKDF2 衍生金鑰。

Reset()

重設作業的狀態。

ToString()

傳回代表目前物件的字串。

(繼承來源 Object)

適用於

另請參閱