Decrypting the file is simply the reverse process. You again create an implementation instance, and then read the real initialization vector and key from the file and replace the random values that were generated by the call to Create() . With these in place, create a crypto stream and wrap it around the file stream, and then read from it. The information is decrypted as you read.
Here's snippet from a console application that reads secret.txt and decrypts it:
Rijndael* rijndael2 = Rijndael::Create(); FileStream* fs2 = new FileStream("secret.txt",FileMode::Open); unsigned char realIV __gc = new unsigned char __gc[rijndael2->IV->Length]; fs2->Read(realIV,0,rijndael2->IV->Length); rijndael2->IV = realIV; unsigned char realKey __gc = new unsigned char __gc[rijndael2->Key->Length]; fs2->Read(realKey,0,rijndael2->Key->Length); rijndael2->Key = realKey; ICryptoTransform* transform2 = rijndael2->CreateDecryptor(); CryptoStream* cs2 = new CryptoStream(fs2,transform2,CryptoStreamMode::Read); StreamReader* sr = new StreamReader(cs2); String* plaintext2 = sr->ReadToEnd(); Console::WriteLine(plaintext2); sr->Close(); cs2->Close(); fs2->Close();
Here are the differences between this code and the code presented in the previous section:
This code takes advantage of the fact the key and initialization vectors are always the same length in the Rijndael algorithm. As a result the length of the random key and initialization vector generated by Create() can be used to allocate space for the real values to be read from the file.
Test this code yourself. Use the sample from the encryption section to fill secret.txt with an initialization vector, a key, and some encrypted text. Then run this code to read secret.txt and write out the original text. You should see the sentence you originally entered.
If you changed the way the first sample saved the initialization vector and key, make sure you make the corresponding changes to this code.