Click here to Skip to main content
15,880,891 members
Articles / Desktop Programming / MFC
Article

.NET Symmetric File Encryption Object

Rate me:
Please Sign up or sign in to vote.
3.00/5 (4 votes)
13 Aug 20024 min read 90.7K   1K   14   9
File encryption object using Managed Extensions for C++

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:

MC++
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.
MC++
#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.
MC++
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.
MC++
CCrypto * myCrypto = new CCrypto ();
// Create key file of c:\mykey.key with 512 bytes of random data
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.
MC++
CCrypto * myCrypto = new CCrypto ();
// Wipe file with 10 patterns before deleting
myCrypto->WipeFile ("c:\\PersonalNotes.txt",10);
Encrypting a file using the 256 bit Rijndael algorithm and a file key.
MC++
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.
MC++
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.
MC++
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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralHi Pin
NapCrisis24-Sep-08 22:26
NapCrisis24-Sep-08 22:26 
GeneralFilename scrambling Pin
lyris1-Sep-08 9:40
lyris1-Sep-08 9:40 
Generalerror C3828: 'MyCrypto::CCrypto': placement arguments not allowed while creating instances of managed classes Pin
nlesser15-Jul-04 11:39
nlesser15-Jul-04 11:39 
GeneralRe: error C3828: 'MyCrypto::CCrypto': placement arguments not allowed while creating instances of managed classes Pin
nlesser15-Jul-04 13:29
nlesser15-Jul-04 13:29 
GeneralPassword and encryption key Pin
purer25-Mar-04 3:17
purer25-Mar-04 3:17 
QuestionIs WipeFile really wiping? Pin
Drizz't15-Sep-03 18:21
Drizz't15-Sep-03 18:21 
AnswerRe: Is WipeFile really wiping? Pin
Bill Ferreira16-Sep-03 11:56
Bill Ferreira16-Sep-03 11:56 
You're right. The FileStream object that I've been using is a buffered I/O operation and there not actually wiping the files. I can't remember why I decided using or how I could have used it without checking the specifications of the object.

I've been writing code for a long time and I can't say this is my first bug. But I must say I'm a little embarrassed to say the least. This is a good case for the need of peer review.

The I/O operation should be a low level unbuffered type of operation. But even still, I would be a little skeptical of how much optimization abstract languages such as Java and the .NET runtime based languages places on I/O operations. As with anything else I guess you just really need to question what’s happening in the code and then validate with hard evidence.

Now I need to research the fix and repost the article. Thank-you for bring this to my attention so that I could fix some of my personal software.

Bill
GeneralRe: Is WipeFile really wiping? Pin
Anonymous21-Sep-03 18:15
Anonymous21-Sep-03 18:15 
GeneralMissing Source ZIP Pin
Vadim Tabakman13-Aug-02 13:55
Vadim Tabakman13-Aug-02 13:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.