David Wong wrote:
>
> Ok, thanks Giuliano ,
> my question is...
Hmmm... there are some things you should be aware of then...
CryptoPP deals with symmetric encryption (like AES) at different levels.
You can use the raw encryptor or use the higher model layers which deal
with everything.
>From what you want, it's probably better you leave the job to crypto++
so, let me introduce the pipe model.
In order to encrypt/decrypt data, crypto++ uses the pipe model, in
practice you put data inside the pipe from one end and retrieve
processed data from the other end (do not assume they are of the same
length).
But since the pipe has limited size, you cannot expect to put everthing
inside before consuming digested/processed data from the other end.
So basically you have to feed the system with small portions of input
data and check if there's something available in the output buffer. If
so, retrieve it to leave space for data is coming after.
When you finished with the input, you just tell it to the system, so he
can flush its pending buffers.
After you declared no more input is available, you just have only to
consume the remianing output and then you're done.
There's no need to worry about the blocksize. This is just handled by
the library internally.
I'll make an example from a program of mine (maybe there're some errors
because I'm deleteing unimportant housekeeping code):
--------------------------------------------------------------------------------
// h1 is the handle of input file, h2 is the handle of output file.
// Write iv directly to disk before entering the pipe main loop, for you
have
// to get it back when you decrypt the file.
byte *myBuff = new byte[BIGBUFFER];
BlockTransformation *blockCipher = new CAST128Encryption(session_key);
CBCPaddedEncryptor *cast = new CBCPaddedEncryptor(*blockCipher,iv);
BufferedTransformation *handle;
// If you want to compress file befoure encrypting just branch here...
if(compression_method == DEFLATE_COMPRESS)
{
// Deflating & encrypting data
handle = new Deflator(cast);
}
else
{
// Only encrypting data
handle = cast;
}
int done = 0;
int err = 0;
int block;
encrypted_datablock_size = 0;
decrypted_datablock_size = 0;
// This is the pipe main loop. It writes the encryptor output to disk
and
// feeds the encryptor with the input file. The loop is exited
immediately
// if an error occurs, or if both the input is finished and all the
output
// has been consumed (written to disk).
while((!done || handle->AnyRetrievable() ) && err == 0)
{
// Write everything we can to disk !
// The first time we get here, the output buffer is empty, so
// this branch is skipped...
while( handle->AnyRetrievable() )
{
// Be sure not to retrieve more data than the allocated buffer can
hold.
block = __min(BIGBUFFER,handle->MaxRetrievable());
handle->Get(myBuff,block); // Read from encryptor output
// Write encrypted data to disk !
if( fwrite(myBuff,1,block,h2) != block )
{
// Handle write error !!!
err=2;
}
else
{
encrypted_datablock_size+=block;
}
}
// Done is set when there's no more input with which to feed the
encryptor
if(!done)
{
block = fread(myBuff,1,BIGBUFFER,h1);
fedIn+=block;
if(block > 0)
{
// Feed the encryptor
handle->Put(myBuff,block);
decrypted_datablock_size+=block;
}
else if(block == 0)
{
// No, more input. Declare a message end and
// keep cycling in the outer loop until we
// consume all the output.
handle->MessageEnd();
done = 1;
}
else
{
// Handle read error !
err = 1;
}
}
}
delete handle;
delete blockCipher;
delete[] myBuff;
-------------------------------------------------------------------------------------------------------------------
you can set BIGBUFFER from 4k to 128k.
Also notice that using the library in the proper way, you can easily add
a compression switch with a few lines.
I leave to complete the encryptor and write the decryptor as an
exercise.
Bye,
--
Giuliano Bertoletti
e-Security Manager
Intrinsic - Security Monitoring
http://www.intrinsic.it
COOL-FIRE: la soluzione Firewall per Windows NT/2000
http://www.symbolic.it/Prodotti/cool-fire.html
SYMBOLIC S.p.A. Tel: +39 0521 776180 / Fax: +39 0521 776190