Abstract
I would have paid a month's worth of salary to get a library as extensive as the .NET Framework class library.
The reason why I say that is because using the .NET Framework library, I can easily shave off weeks in development
time on a single project. But, as with any other library you still need to develop your own objects to abstract the
complexity of the underlying framework. The .NET Framework is no exception.
The CCrypto
object I am demonstrating shows how to use the .NET Framework Cryptographic Service
classes to encrypt and
decrypt files. This article documents the object, and includes code samples on implementing it.
With anything new there is a learning curve. For me, the .NET Framework and
Managed Extensions for C++ does not change that rule. With encryption near and
dear to my heart I decided to begin developing crypto objects that hide the
complexity of the framework, this article shows how easy it is done.
This article is the first in a three part series on symmetric encryption with
the .NET Framework using Managed Extensions for C++. I'll follow this article
with a command line utility implementing the object, and an article covering
an overview of symmetric encryption and the classes in the .NET Cryptographic
Services.
You will need the Visual C++.NET to compile and test the code. I have assumed you are familiar with Managed Extensions for C++.
The CCrypto Object
The purpose of CCrypto
is to abstract all the .NET Framework classes to encrypt, decrypt, wipe,
and fingerprint (hash) files.
To use the CCrypto
object you need to include the definition header for the object and reference the
namespace. The CCrypto
object consumes any derived encryption algorithm of the SymmetricAlgorithm
class. When encrypting or
decrypting, you also need
to consume a HashAlgorithm
derived class for hashing.
The selection of the hashing function must have a similar key space as the encryption function. So, if you are using RC2 which
produces uses a 128 bit key, use the MD5CryptoServiceProvider()
object which has a 128 bit key space. Mix and matching the key
spaces with throw an exception.
The CCrypto
object does not directly use the passphrase or key file as the encryption key. Rather, it creates a hash of the
passphrase or key file and uses the hash as the key.
The object's definition and implementation code is listed after the code snippets demonstrating the use of the object.
Issues
I am not aware of any issues with the object. I was not able to find any test vectors to test Microsoft's implementation
of the symmetric encryption algorithms. I have also not tested the quality of the cryptographic random number generator.
I would have liked it if the encryption / decryption worked faster. With my P4 1.6Ghz, ATA100 drive, XP Pro,
I achieved 7.6 Mb/s encryption on a 20 Mb file using the RC2 algorithm.
Constructors
CCrypto (SymmetricAlgorithm * CryptoServiceProvider, HashAlgorithm * HashServiceProvider); |
CCrypto (HashAlgorithm * HashServiceProvider); |
CCrypto () |
Public Methods
Encrypt |
Encrypts a file |
Decrypt |
Decrypts a file |
WipeFile |
Securely removes the file |
HashFile |
Gets the file's fingerprint |
CreateKeyFile |
Creates a file with random data |
Properties
get_HashProvider |
Sets the hash provider |
set_SetKeyPhrase |
Sets the Key phrase for encryption/decryption |
set_SetFileKey |
Sets the Key file for encryption/decryption |
Protected Methods
Crypt |
Performs the encryption/decryption |
HandleException |
Exception handler |
Implementations:
bool Encrypt (String * inFilePath, String * OutfilePath)
bool Decrypt (String * inFilePath, String * OutfilePath)
bool WipeFile (String * inFilePath, int nWipes )
bool CreateKeyFile (String * outfilepath, unsigned int nBytes)
Byte HashFile (String * inFile )[]
bool Crypt (int Direction, String * inFilePath, String * OutfilePath);
virtual void HandleException (Exception * e)
__property void set_SetKeyPhrase (String * Phrase)
__property HashAlgorithm * get_HashProvider ()
__property void set_HashProvider (HashAlgorithm * myHashServiceProvider)
__property void set_SetFileKey (String * FileKeyPath)
Code Examples
I have referenced the namespaces of
System::Security::Cryptography
and
MyCrypto
so that
the samples are more readable. To use the object, you need to include the Crypto.h header. Below is an example
of the include and namespace references.
#using <system.dll>
#include "Crypto.h"
using namespace System::Security::Cryptography ;
using namespace MyCrypto ;
This code snippet to retrieve a file's fingerprint and displays that to the console.
CCrypto * myCrypto = new CCrypto (new MD5CryptoServiceProvider());
Console::WriteLine( BitConverter::ToString (myCrypto->HashFile ("c:\\encnotes2.txt")) );
This code example creates a file with random data to be used as a key. The random data comes from the random number
generator that is part of the .NET Cryptographic Services. This is the preferred way to encrypt the data. The key
file can reside on disk, smart card, or USB key.
CCrypto * myCrypto = new CCrypto ();
myCrypto->CreateKeyFile ("c:\\mykey.key",512);
This example demonstrates how to wipe a file that is no longer needed. Before
deleting the file from the device the file will be over written with ten patterns.
CCrypto * myCrypto = new CCrypto ();
myCrypto->WipeFile ("c:\\PersonalNotes.txt",10);
Encrypting a file using the 256 bit Rijndael algorithm and a file key.
CCrypto * myCrypto = new CCrypto (new RijndaelManaged(),new SHA256Managed());
myCrypto->CreateKeyFile ("c:\\mykey.key",512);
myCrypto->SetFileKey = "c:\\mykey.key";
myCrypto->Encrypt ("c:\\PersonalNotes.txt","c:\\PersonalNotes.txt.enc");
To decrypt the file we need to use the same algorithm and key.
CCrypto * myCrypto = new CCrypto (new RijndaelManaged(),new SHA256Managed());
myCrypto->SetFileKey = "c:\\mykey.key";
myCrypto->Decrypt ("c:\\PersonalNotes.txt.enc","c:\\PersonalNotes.txt");
Here is an example of encrypting a file using a phrase.
CCrypto * myCrypto = new CCrypto (new RijndaelManaged(),new SHA256Managed());
myCrypto->SetKeyPhrase = S"You can place any valid string here.";
myCrypto->Encrypt ("c:\\PersonalNotes.txt","c:\\PersonalNotes.txt.enc");
I am interested in hearing what you have to say regarding the CCrypto
object or this article. If you have any questions, comments,
or criticisms, don't hesitate to let me know.