Rfc2898DeriveBytes Constructor (String^, array<Byte>^)
Initializes a new instance of the Rfc2898DeriveBytes class using a password and salt to derive the key.
Assembly: mscorlib (in mscorlib.dll)
Parameters
- password
-
Type:
System::String^
The password used to derive the key.
- salt
-
Type:
array<System::Byte>^
The key salt used to derive the key.
| Exception | Condition |
|---|---|
| ArgumentException | The specified salt size is smaller than 8 bytes or the iteration count is less than 1. |
| ArgumentNullException | The password or salt is null. |
The salt size must be 8 bytes or larger.
RFC 2898 includes methods for creating a key and initialization vector (IV) from a password and salt. You can use PBKDF2, a password-based key derivation function, to derive keys using a pseudo-random function that allows keys of virtually unlimited length to be generated. The Rfc2898DeriveBytes class can be used to produce a derived key from a base key and other parameters. In a password-based key derivation function, the base key is a password and the other parameters are a salt value and an iteration count.
For more information about PBKDF2, see RFC 2898, "PKCS #5: Password-Based Cryptography Specification Version 2.0," available on the Request for Comments Web site. See section 5.2, "PBKDF2," for complete details.
Security Note
|
|---|
Never hard-code a password within your source code. Hard-coded passwords can be retrieved from an assembly by using the Ildasm.exe (IL Disassembler), by using a hexadecimal editor, or by simply opening up the assembly in a text editor such as Notepad.exe. |
The following code example uses the Rfc2898DeriveBytes class to create two identical keys for the TripleDES class. It then encrypts and decrypts some data using the keys.
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. TripleDES^ encAlg = TripleDES::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. TripleDES^ decAlg = TripleDES::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 ); } } }
Available since 2.0
Silverlight
Available since 2.0
Windows Phone Silverlight
Available since 7.0
