Decrypt file using AES::CBC

2,717 views
Skip to first unread message

Rash

unread,
Sep 2, 2007, 1:33:45 AM9/2/07
to Crypto++ Users
Hello All,
Following are my specifications to encrypt/decrypt files using
AES::CBC mode

Encrypt process:
1) 8 bytes random IV ( Initialization Vector ).
Insert the 8 bytes random IV to the beginning of the data stream.

2) Key length with 16 bytes ( digest using MD5 ).
3) padding method compatible with RFC 2898.
4) Encrypt the file.

Decrypt process:
1) Read the first 8 bytes block and ignore it.
2) Digest the key using MD5.
3) Use the same padding method used when encrypting the file.
4) Decrypt the file.

To encrypt the file here is my code
void encryptFile(const char* password, const char* inputFileName,
const
char* outputFileName)
{
byte pass[ AES::BLOCKSIZE ]; // digest of password
byte iv[ 8 ]; // Initial Vector (IV)

AutoSeededRandomPool rng; // random number generator
try
{
// digest password
StringSource( password, true,new HashFilter(*(new MD5), new
ArraySink(pass, AES::BLOCKSIZE)) );

// random Initial Vector
rng.GenerateBlock(iv, 8);

// create object for encrypting
AES::Encryption aesEncryption(pass,
CryptoPP::AES::DEFAULT_KEYLENGTH);
CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption,
iv);

StreamTransformationFilter *encryptor;
encryptor = new StreamTransformationFilter(cbcEncryption, new
FileSink(outputFileName) );

encryptor->Put(iv, 8);

// "bind" a file and encrypt one
FileSource(inputFileName, true, encryptor);
}
catch(CryptoPP::Exception &e)
{
return;
}
}
void decryptFile(const char* password, const char*inputFileName,const
char*outputFileName)
{
//help me to write the decrypt functionality
}

How do I decrypt the file? I'm unable to read the first 8 bytes block
and ignore it.
Please help me to write the decrypt function satisfying the above
specifications.

Thanks in advance

Rash

unread,
Sep 2, 2007, 1:44:27 AM9/2/07
to Crypto++ Users
I tried the following but I get the exception, "ciphertext block is
not a multiple of block size". Please help.

void decryptFile(const char* password, const char*inputFileName,const
char*outputFileName)
{
byte pass[ AES::BLOCKSIZE ];
byte iv[ 8 ];
byte head_file[ 8 ];

memset(iv, 0, 8);

try
{
FileSource source(inputFileName, false);


StringSource( password, true,new HashFilter(*(new MD5), new
ArraySink(pass, AES::BLOCKSIZE)) );

CryptoPP::AES::Decryption aesDecryption(pass,
CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Decryption
cbcDecryption( aesDecryption, iv );

// get and encrypt first block
source.Pump(8);
source.Get(head_file, 8);

// "bind" decryptor to output file
source.Attach( new StreamTransformationFilter(cbcDecryption,
new FileSink((outputFileName) ) ));

// push the rest data
source.PumpAll();
}
catch(CryptoPP::Exception &e)
{
return ;

Rash

unread,
Sep 2, 2007, 2:50:27 AM9/2/07
to Crypto++ Users
Ok here is what I have been trying, Now the problem is I'm unable to
retrieve the first 5 bytes.
If the input is
"The library is an powerful and elegant tool for performing complex
cryptography"
I get the output as
"}ýŸ¼tÛ=rary is an powerful and elegant tool for performing complex
cryptography"

Here is what I did. help me to fix this problem


void encryptFile(const char* password, const char* inputFileName,
const char* outputFileName)
{
byte pass[ AES::BLOCKSIZE ]; // digest of password
byte iv[ 8 ]; // Initial Vector (IV)

AutoSeededRandomPool rng;

// digest password
StringSource( password, true, new HashFilter(*(new SHA256), new
ArraySink(pass, AES::BLOCKSIZE)) );

// random Initial Vector
rng.GenerateBlock(iv, 8);

// create object for encrypting
AES::Encryption aesEncryption(pass,
CryptoPP::AES::DEFAULT_KEYLENGTH);
CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption,
iv);

StreamTransformationFilter *encryptor;
encryptor = new StreamTransformationFilter(cbcEncryption, new
FileSink(outputFileName) );
encryptor->Put(iv, 8);

// "bind" a file and encrypt one
FileSource(inputFileName, true, encryptor);
}

void decryptFile(const char* password, const char*inputFileName,const


char* outputFileName)
{
byte pass[ AES::BLOCKSIZE ];

byte iv[ 8 ];
byte head_file[ 8 ];

memset(iv, 0, 8 );
try
{

StringSource( password, true, new HashFilter(*(new SHA256), new
ArraySink(pass,AES::BLOCKSIZE)) );

CryptoPP::AES::Decryption aesDecryption(pass,
CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Decryption
cbcDecryption( aesDecryption, iv );

StreamTransformationFilter *decryptor;
decryptor = new
StreamTransformationFilter(cbcDecryption, new
FileSink(outputFileName) );
decryptor->Get( head_file, 8 );

FileSource(inputFileName, true, decryptor);
}
catch(CryptoPP::Exception &e)
{
return;

Mouse

unread,
Sep 2, 2007, 12:42:57 PM9/2/07
to Rash, Crypto++ Users
Your problem is due to the fact that your "automatic" stream decryptor is reading the file from the very beginning. And due to the error in configuring encryptor, the first block can't be decrypted properly.

See the attached source code for correction. I've tested the corrected code under Cygwin with Crypto++ v5.5.1 and it worked properly.


Rash wrote:
Ok here is what I have been trying, Now the problem is I'm unable to
retrieve the first 5 bytes.
If the input is
"The library is an powerful and elegant tool for performing complex
cryptography"
I get the output as
"}ýŸ1/4 tÛ=rary is an powerful and elegant tool for performing complex
cryptography"

Here is what I did. help me to fix this problem
void encryptFile(const char* password, const char* inputFileName,
const char* outputFileName)
{
    byte pass[ AES::BLOCKSIZE ];	// digest of password
    byte iv[ 8 ];			// Initial Vector (IV)

    AutoSeededRandomPool rng;

    // digest password
    StringSource( password, true, new HashFilter(*(new SHA256), new
ArraySink(pass, AES::BLOCKSIZE)) );

    // random Initial Vector
    rng.GenerateBlock(iv, 8);

    // create object for encrypting
    AES::Encryption aesEncryption(pass,
CryptoPP::AES::DEFAULT_KEYLENGTH);
    CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption,
iv);

    StreamTransformationFilter *encryptor;
    encryptor = new StreamTransformationFilter(cbcEncryption, new
FileSink(outputFileName) );
    encryptor->Put(iv, 8);

    // "bind" a file and encrypt one
    FileSource(inputFileName, true, encryptor);
}

void decryptFile(const char* password, const char*inputFileName,const
char* outputFileName)
{
    byte pass[ AES::BLOCKSIZE ];
    byte iv[ 8 ];
    byte head_file[ 8 ];

    memset(iv, 0, 8 );
    try
	{
		StringSource( password, true, new HashFilter(*(new SHA256), new
ArraySink(pass,AES::BLOCKSIZE)) );

		CryptoPP::AES::Decryption aesDecryption(pass,
CryptoPP::AES::DEFAULT_KEYLENGTH);
		CryptoPP::CBC_Mode_ExternalCipher::Decryption
cbcDecryption( aesDecryption, iv );

		StreamTransformationFilter *decryptor;
                decryptor = new
StreamTransformationFilter(cbcDecryption, new
FileSink(outputFileName) );
		decryptor->Get( head_file, 8 );

		FileSource(inputFileName, true, decryptor);
	}
	catch(CryptoPP::Exception &e)
	{
		return;
	}
}

On Sep 2, 10:44 am, Rash <raj143p...@gmail.com> wrote:
  
rash-enc.cc

Jeffrey Walton

unread,
Sep 2, 2007, 4:04:16 PM9/2/07
to Rash, Crypto++ Users
Hi Rash,

If I recall correctly, the IV should be the same size as the block
size. This is because once a block is encrypted at stage i, it is fed
into stage i+1. For the first pass (stage 0), there is no stage -1. So
an IV is required.

Perhaps refreshing the topic with Schneier's Applied Cryptography or
Menenze (et al) Handbook of Applied Cryptography will be of assistance
to you.

As for stepping over your IV in the data stream, take a look at sample
4 in this example. It steps over salt housed in a std::string.
http://www.codeproject.com/cpp/AESProductKey.asp

Jeff

_PINUX_

unread,
Oct 16, 2007, 6:02:33 PM10/16/07
to Crypto++ Users
Hi,

I am reading this to get some hints about how to use crypto++ to en/
decrypt files. I am a bit confused by Mouse's answer though. I have
two questions here:

+ Why did he choose 16-byte zeros as the initial vector for CBC mode?
Apparently my guess is wrong and it seems the first 16-byte random
prefix of the file is used as the real initial vector. If the file
prefix guess is true then how can the decryptFile function decrypt the
first 16-byte without knowning the IV.

+ how does the function call cbcDecryption.ProcessData((byte
*)garbage, (const byte *)iv_garbage, 16); make the decryptor state
adjust to IV, and file position pointer advance to the past-IV spot.

Thanks

Mouse

unread,
Oct 16, 2007, 9:54:41 PM10/16/07
to _PINUX_, Crypto++ Users
> I am reading this to get some hints about how to use crypto++
> to en/ decrypt files. I am a bit confused by Mouse's answer
> though. I have two questions here:
>
> + Why did he choose 16-byte zeros as the initial vector for CBC mode?

Because for the sake of correctness, one should set IV to something. And
since you did not provide the means to transfer the "real" IV to the
decryptor - I chose to set it explicitly to something simple such as all
zeroes. It is cryptographically OK because the plaintext is prefixed with
random 16 bytes (that serve cryptographically as IV - though they are *not*
IV).

> Apparently my guess is wrong and it seems the first 16-byte
> random prefix of the file is used as the real initial vector.

No, don't mix IV (that is explicitly fed to the crypto engine) with prefix
(that is prepended to the data). End result is similar - but the processing
is very different.

> If the file prefix guess is true then how can the decryptFile
> function decrypt the first 16-byte without knowning the IV.

The first 16 bytes of the file decrypt into garbage because decryptor
doesn't have the correct IV - but since your random prefix carries no
information anyway, the only symptom of your error is that your decrypted
text is prepended with 16 garbage bytes.



> + how does the function call cbcDecryption.ProcessData((byte
> *)garbage, (const byte *)iv_garbage, 16); make the decryptor state
> adjust to IV, and file position pointer advance to the past-IV spot.

I leave this as a home exercise.

_PINUX_

unread,
Oct 17, 2007, 4:08:09 AM10/17/07
to Crypto++ Users
Now I understand your answer to my first question:

The process takes this way:

+ The IV(16-byte zeros) XOR the first 16-byte of plaintext (which is a
random number);
+ Use the key to encrypt the result then we get the first block of
ciphertext
+ Feed this block as an input (we can see this block as an IV to the
next round encryption) XOR the next block of plaintext
+ The real plain text encryption takes place from here...

_PINUX_

unread,
Nov 2, 2007, 8:06:29 AM11/2/07
to Crypto++ Users
Hi Mouse I tested your code in VS2005. I have got a couple of
questions and appreciate that you can help me on any of them.

+ Take the encryption code for example. You allocate memory for
'encryptor' but I never see you delete them in your code. I ran the
code in a debug mode and found out after the FileSource is called the
memory of 'encryptor' object is freed magically. Is this a smart
pointer design in CryptoPP?

+ Does CryptoPP AES implementation support 32-byte block size? Seems
not.

+ As you know, we need to consider the padding when using CBC mode so
that we can process data in multiple of block size. According to
CryptoPP's FAQ:

"Alternatively, you can wrap StreamTransformationFilter around the
mode object and use it as a Filter object. StreamTransformationFilter
will take care of buffering data into blocks for you when needed.

std::string ciphertext;
StreamTransformationFilter cfbEncryptor(cfbEncryption, new
StringSink(ciphertext));
cfbEncryptor.Put(plaintext, 100);
// input more plaintext here if needed
cfbEncryptor.MessageEnd(); "

Your decryption code throws an exception saying the data is not a
multiple of block size. Is this because padding should be added in the
encryption code and how?

I can't get help from the sample code because it uses MessageEnd() at
the end of the encryption. I can't use encryptor->MessageEnd() in your
code because the encryptor object is destroyed after the
FileSource(...).

Many thanks

_PINUX_

unread,
Nov 2, 2007, 8:37:33 AM11/2/07
to Crypto++ Users
It seems when using StreamTransformationFilter it should buffer the
incomplete block automatically when needed. But:

+ why cfbEncryptor.MessageEnd(); is still called in the FAQ sample
code.

+ If StreamTransformationFilter takes care of the padding, why the
data is not a multiple of block size is thrown in the decryption code.
There is a slight change in my test. I use MAX_KEYLENGTH. So here's
the scenario:

Key size 256 Block size 128 IV size 128

Thanks

Jeffrey Walton

unread,
Nov 2, 2007, 11:23:11 AM11/2/07
to _PINUX_, Crypto++ Users
Hi _PINUX_,

> + why cfbEncryptor.MessageEnd(); is still called in the
> FAQ sample code.

How is the filter suppose to know when the stream ends? The filter's
job is buffering - it accumulates and then pushes 'blocksize' chunks
to the encryption object.

Jeff

Mouse

unread,
Nov 2, 2007, 3:28:47 PM11/2/07
to _PINUX_, Crypto++ Users
> Hi Mouse I tested your code in VS2005. I have got a couple
> of questions and appreciate that you can help me on any of
> them.

Sure.

> Take the encryption code for example. You allocate memory
> for 'encryptor' but I never see you delete them in your code.

In the example I gave I did not bother deleting the encryptor object,
letting the memory be reclaimed after the program completes.

> I ran the code in a debug mode and found out after the FileSource
> is called the memory of 'encryptor' object is freed magically.

That I cannot explain as I don't know.

> Is this a smart pointer design in CryptoPP?

Wei Dai would be the best one to answer this question. I don't know if
Crypto++ does or does not use Smart Pointers.

> Does CryptoPP AES implementation support 32-byte block size?
> Seems not.

Since 32-byte-block AES does not exist, the answer is obvious. Rijndael
design did support 32-byte blocks, but standardized AES does not.

> As you know, we need to consider the padding when using CBC
> mode so that we can process data in multiple of block size.

Which is why it usually makes sense to wrap the encryptor in the
StreamTransformationFilter().


std::string ciphertext;
StreamTransformationFilter cfbEncryptor(cfbEncryption, new
StringSink(ciphertext));
cfbEncryptor.Put(plaintext, 100);
// input more plaintext here if needed
cfbEncryptor.MessageEnd(); "

> Your decryption code throws an exception saying the data
> is not a multiple of block size. Is this because padding
> should be added in the encryption code and how?

Sorry, but *my* decryptor did not throw any exceptions - I've tested it
before posting. I don't know the code that *you* wrapped around the
decryptor, so cannot comment.

> I can't get help from the sample code because it uses MessageEnd()
> at the end of the encryption.

Oh so you removed the MessageEnd() at the end of the encryption, so there's
nothing to tell the encryptor "Now there's no more input - therefore pad
whatever data is sitting in the buffer, encrypt it and push it out". And now
you're surprised that your code does not work?

> I can't use encryptor->MessageEnd() in your code because the
> encryptor object is destroyed after the FileSource(...).

That object should NOT just get destroyed all by itself. Something in your
code must be doing something wrong with it. Again, take a look at the
example I posted earlier - it has been tested and works properly.

_PINUX_

unread,
Nov 4, 2007, 4:47:21 AM11/4/07
to Crypto++ Users
Thanks for all your explanation.

> Sorry, but *my* decryptor did not throw any exceptions - I've tested it
> before posting. I don't know the code that *you* wrapped around the
> decryptor, so cannot comment.

I thought that too. I then ran the test using your sample code, rash-
enc.cc without any changes. It works but after I added the more
characters in the plain text file (say up to 2KB). The test ended up
with the exception, the ciphertext is not a multiple of block size
again.

> Oh so you removed the MessageEnd() at the end of the encryption, so there's
> nothing to tell the encryptor "Now there's no more input - therefore pad
> whatever data is sitting in the buffer, encrypt it and push it out". And now
> you're surprised that your code does not work?

Not in the sample code from FAQ. I actually wondered why your code
didn't call MessageEnd() (after the FileSource(...)) until I read
about this in Crypto++ UserGuide:

"PumpAll(). Pumps all messages just like PumpMessages() would if
called with no argument, and then pumps the following uncomplete
message until there is no more data to extract. With FileSource and
StringSource, PumpAll() extracts data like Pump() and then calls
MessageEnd()."

_PINUX_

unread,
Nov 4, 2007, 5:42:50 AM11/4/07
to Crypto++ Users
> > Take the encryption code for example. You allocate memory
> > for 'encryptor' but I never see you delete them in your code.

> In the example I gave I did not bother deleting the encryptor object,
> letting the memory be reclaimed after the program completes.

Yeah. I just wondered without using the 'delete' operator how the
object is destroyed and memory is freed. And this seems to be the
answer

>From the readme file:

"1. If a constructor for A takes a pointer to an object B (except
primitive
types such as int and char), then A owns B and will delete B at A's
destruction. If a constructor for A takes a reference to an object B,
then the caller retains ownership of B and should not destroy it until
A no longer needs it."

_PINUX_

unread,
Nov 5, 2007, 12:06:11 PM11/5/07
to Crypto++ Users
A fix to the file en/decryption code:

Symptom: An exception, the cipher text is not a multiple of block size
is thrown when decrypting data.
Fix: Open the encrypted file in binary mode

...
ifstream inf;
inf.open(inputFileName, ifstream::binary); //open the encrypted
file in binary mode
inf.read(iv_garbage, 16); // absorb
random prefix
...

_PINUX_

grimreaper

unread,
Sep 10, 2010, 3:45:03 AM9/10/10
to cryptop...@googlegroups.com


Mouse-2 wrote:
>
>
>
>
> #include <iostream>
>
> #include <cryptopp/aes.h>
> #include <cryptopp/modes.h>
> #include <cryptopp/sha.h>
> #include <cryptopp/osrng.h>
> #include <cryptopp/files.h>
> #include <cryptopp/filters.h>
>
> USING_NAMESPACE(CryptoPP);
> USING_NAMESPACE(std);
>
> /**************************************************************/
> /* Code to illustrate usage of cryptographic primitives */
> /* provided by Crypto++ library v5.5.1 of Wei Dai. */
> /* */
> /* In particular, the program provides two functions: */
> /* */
> /* 1. Encrypt a file (key based on password) with random IV;*/
> /* */
> /* 2. Decrypt previously encrypted file. */
> /* */
> /* Issue with the original code: */
> /* - set IV in the encryptor but also used it as random */
> /* prefix, so garbage was the 1st encrypted block; */
> /* - did not "fast-forward" the encrypted file past the */
> /* first block (which was encrypted random garbage). */
> /* */
> /* Corrections performed: */
> /* - fixed encryptor by leaving random block prefixed, */
> /* but removing redundancy (having it in encryptor); */
> /* - fixed decryptor (see the source code). */
> /* */
> /*==========================================================*/
> /* Written by: */
> /* Rash <raj14...@gmail.com> */
> /* */
> /* Modified by: */
> /* Mouse <urim...@optonline.net> */
> /* Sun Sep 2, 12:25:00 2007 */
> /* */
> /************************************************************/
> /* */
> /* Copyright (C) 2007 Rash <raj14...@gmail.com> */
> /* Copyright (C) 2007 Mouse <urim...@optonline.net> */
> /* */
> /************************************************************/


>
> void encryptFile(const char* password, const char* inputFileName,
> const char* outputFileName)
> {
> byte pass[AES::BLOCKSIZE]; // digest of password

> byte iv[16]; // Initial Vector (IV), misused
> // by original author
> byte true_iv[16]; // real IV used - set to zero


>
> AutoSeededRandomPool rng;
>
> // digest password

> StringSource(password, true,

> new HashFilter(*(new SHA256),
> new ArraySink(pass, AES::BLOCKSIZE)));
>
> // random Initial Vector

> rng.GenerateBlock(iv, 16);
> memset(true_iv, 0, 16);


>
> // create object for encrypting
> AES::Encryption aesEncryption(pass,
> CryptoPP::AES::DEFAULT_KEYLENGTH);
> CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption,

> true_iv);


>
> StreamTransformationFilter *encryptor;
> encryptor = new StreamTransformationFilter(cbcEncryption,
> new FileSink(outputFileName) );
>

> encryptor->Put(iv, 16); // this prefixes the file with random block (not
> IV)
> // Cryptographically it is equivalent to IV, so just as
> good


>
> // "bind" a file and encrypt one
> FileSource(inputFileName, true, encryptor);
> }
>
>
> void decryptFile(const char* password, const char*inputFileName,

> const char* outputFileName)
> {
> byte pass[AES::BLOCKSIZE];

> byte iv[16]; // here's 1st problem: AES IV is 16 bytes
> byte head_file[16]; // so must skip 16 bytes, not 8.
>
> memset(iv, 0, 16); // very correct - in fact the encryptor prefixes file
> // with a random block, so no need to pass the IV explicitly.
>
> try {
> StringSource(password, true, new HashFilter(*(new SHA256), new


> ArraySink(pass,AES::BLOCKSIZE)));
>
> CryptoPP::AES::Decryption aesDecryption(pass,
> CryptoPP::AES::DEFAULT_KEYLENGTH);
> CryptoPP::CBC_Mode_ExternalCipher::Decryption
> cbcDecryption(aesDecryption, iv);
>
> StreamTransformationFilter *decryptor;
> decryptor = new
> StreamTransformationFilter(cbcDecryption, new
> FileSink(outputFileName));
>
>

> // decryptor->Get(head_file, 16); // does not do anything useful,
> wrong here
> // We must somehow decrypt 1st block of the input file, without
> sending the
> // result into the output file.
> char garbage[16], iv_garbage[16]; // place for IV stuff
> ifstream inf;
> inf.open(inputFileName); inf.read(iv_garbage, 16); // absorb random
> prefix
>
> // Decrypt random prefix (with zero IV) to some dummy buffer to get
> // (a) decryptor state adjusted to IV, and
> // (b) file position pointer advanced to the past-IV spot.


> cbcDecryption.ProcessData((byte *)garbage, (const byte *)iv_garbage,
> 16);
>

> // NOW can run the decryption engine in "automatic" mode
> FileSource(inf, true, decryptor);
>
> inf.close(); // to be nice
> }
> catch(CryptoPP::Exception &e)
> {
> cerr << "Caught exception during decryption!" << endl;
> return;
> }
> }
>
> int main(int argc, char *argv[])
> {
> const char *pwd = "not-so-complicated parole";
> const char *pfn = "plain.txt";
> const char *cfn = "cipher.dat";
> const char *ofn = "plain2.txt";
>
> // Create test plaintext file "plain.txt"
> ofstream plain;
> plain.open(pfn);
> plain << "An excellent test of file encryption techniques.\n";
> plain << "This test will not demonstrate many tricks though.\n";
> plain.close();
>
> // Invoke encryptor to encrypt into "cipher.dat"
> encryptFile(pwd, pfn, cfn);
>
> // Invoke decryptor to decrypt into "plain2.txt"
> decryptFile(pwd, cfn, ofn);
>
> exit(0);
> }
>
>


your code is working on text but when i used a binary file like an image it
failed
please help
what changes should i make
please reply
thanks in advance
--
View this message in context: http://old.nabble.com/Decrypt-file-using-AES%3A%3ACBC-tp12446523p29674413.html
Sent from the Crypto++ Users mailing list archive at Nabble.com.

Mike Hamburg

unread,
Sep 10, 2010, 1:38:33 PM9/10/10
to grimreaper, cryptop...@googlegroups.com
grimreaper,

We can probably help you on this list, but you'll need to provide more
information than this. The code that was provided ought to work equally
well for text and binary, so let's try to figure out what's wrong with
your example.

In what way does decryption fail?

Does it throw an exception? What exception?

Does it produce a corrupt file? In what way is the file corrupt? (That
is, in what way is it different from the original file?) Does it have
its CR's replaced with CRLF's? Does it have null bytes removed? Is it
the same size or a different size? Does it have random junk at the
beginning or end? Does it fail in the same way every time, or does it
depend on the random "IV" block? Does the output file just have the
wrong extension (.txt) for your OS to open it?

What OS are you running (Windows, right? What version?), and what
version of Crypto++?

Cheers,
Mike

GrimReaper

unread,
Sep 11, 2010, 2:11:47 AM9/11/10
to Crypto++ Users
exception is thrown that decryption failed

i tried with small files(1kb or less it worked like a charm)

but size greater than that failed , with throwing exception that
decryption failed

On Sep 10, 10:38 pm, Mike Hamburg <mhamb...@stanford.edu> wrote:
> grimreaper,
>
> We can probably help you on this list, but you'll need to provide more
> information than this.  The code that was provided ought to work equally
> well for text and binary, so let's try to figure out what's wrong with
> your example.
>
> In what way does decryption fail?
>
> Does it throw an exception?  What exception?
>
> Does it produce a corrupt file?  In what way is the file corrupt?  (That
> is, in what way is it different from the original file?)  Does it have
> its CR's replaced with CRLF's?  Does it have null bytes removed?  Is it
> the same size or a different size?  Does it have random junk at the
> beginning or end?  Does it fail in the same way every time, or does it
> depend on the random "IV" block?  Does the output file just have the
> wrong extension (.txt) for your OS to open it?
>
> What OS are you running (Windows, right?  What version?), and what
> version of Crypto++?
>
> Cheers,
> > >   /*                   Rash <raj143p...@gmail.com>            */
> > >   /*                                                          */
> > >   /* Modified by:                                             */
> > >   /*                   Mouse <urimob...@optonline.net>        */
> > >   /*                   Sun Sep 2, 12:25:00 2007               */
> > >   /*                                                          */
> > >   /************************************************************/
> > >   /*                                                          */
> > >   /* Copyright (C) 2007 Rash  <raj143p...@gmail.com>          */
> > >   /* Copyright (C) 2007 Mouse <urimob...@optonline.net>       */
> > View this message in context:http://old.nabble.com/Decrypt-file-using-AES%3A%3ACBC-tp12446523p2967...

GrimReaper

unread,
Sep 11, 2010, 2:20:05 AM9/11/10
to Crypto++ Users
I am running qt 4.6,mingw compiler
windows 7
cryptopp 5.5.2 version


The file was corrupted in a way that i decrypted that the image only
top part of it was decrypted right(1/7th part of image form top
recovered)(total image size7 kb) rest was blank

on bigger images it corrupted


I am not much in security i just wanted to pass infile outfile
password and it should returned encrypted file and decvrypted file, i
am trying to do that with aes , des ,triple des blowfish


for aes

i tried this link, its the code for aes file encryption and this is
working very good with full decryption
http://swarmapps.wordpress.com/2009/11/24/a-simplification-wrapper-for-the-crypto-library/

if you can tell me how to convert this for blowfish , this might help
i need not dwelve into much details


Thank you for your reply

GrimReaper

unread,
Sep 11, 2010, 5:12:55 AM9/11/10
to Crypto++ Users
i was finally able to encrypt files and have the code attached
i just changed algo name in cbcmode to aes and then des and then
blowfish

i just wanted to ask a simple question now, the encrypted sinks of
each algorithm have same sizes, is this right or i have done some
mistake?
cause my project is regarding space computation (memory taken by each
algorithm in each mode) and time taken for encrypting large files

also, i changed cbc to ecb mode it crashed... any suggestions

please reply as you are the only active member

qt 4.6
cryptopp 5.5.2
win7


/// code below

#define CRYPTOPP_DEFAULT_NO_DLL
#include <cryptopp/dll.h>
#ifdef CRYPTOPP_WIN32_AVAILABLE
#include <windows.h>
#endif


#include <iostream>
#include <string>
#include <cstdio>
#include <sstream>
#include <cryptopp/config.h>
#include <cryptopp/hex.h>
#include <cryptopp/files.h>
#include <cryptopp/cryptlib.h>
#include <cryptopp/modes.h>
#include <cryptopp/osrng.h>
#include <cryptopp/filters.h>
#include <cryptopp/aes.h>
#include <cryptopp/des.h>
#include <cryptopp/blowfish.h>

USING_NAMESPACE(CryptoPP)
USING_NAMESPACE(std)
const int MAX_PHRASE_LENGTH=250;

using std::ostringstream;
using std::string;
using std::cout;
using std::endl;

static bool isHex(string checkForHex) {
size_t found;
found = checkForHex.find_first_not_of("0123456789ABCDEF");
if (found!=string::npos) {
// This string has non-hex characters in it
return false;
} else {
// only hex characters
return true;
}
}


static string HexDecode(string hexString)
{
if (isHex(hexString)) {
string binaryString;
StringSource(hexString, true, new HexDecoder(new
StringSink(binaryString)));
return binaryString;
} else {
// it's already binary!
return hexString;
}
}


static string HexEncode(string binaryString) {

if (isHex(binaryString)) {
// This string is already hex, don't convert it!
return binaryString;
} else {
string hexString;
StringSource(binaryString, true, new HexEncoder(new
StringSink(hexString)));
return hexString;
}
}

static string ByteGen(int howManyBytes) {
// returns a new random key of the given byte length
AutoSeededRandomPool rnd;
byte block[howManyBytes];
rnd.GenerateBlock(block, howManyBytes);
string blockString;
blockString.assign((char *)block, sizeof(block));
return blockString;
}

static string BitGen(int howManyBits) {
// returns a new random key in binary of the given bit length
int byteLength = howManyBits/8; // bitLengths always better be
div 8!!
return ByteGen(byteLength);
}



static string hashSHA256(string inputString) {
// returns a SHA-256 encoded hash of the inputString in binary
// always returns 256 bits
SHA256 hash;
byte digest [ SHA256::DIGESTSIZE ];

hash.CalculateDigest( digest, (byte *)inputString.c_str(),
inputString.length() );
string hashString;
hashString.assign((char *)digest, sizeof(digest));

return hashString;
}



static void EncryptFileAES(istream& inFile, ostream& outFile, string
key, string iv, bool &err, string &errMsg) {
// will encrypt the file at filenameIn to filenameOut using
AES
// WARNING: The iv must be known and retained for decryption!!
// key and iv can be hex or binary


// convert the key and iv
key = HexDecode(key);
iv = HexDecode(iv);
try {
// Set up the encrypter
CBC_Mode< CryptoPP::AES >::Encryption e1( (byte
*)key.c_str(), key.length(), (byte *)iv.c_str() );
// encrypt
//if (filenameOut == "cout")
// FileSource( filenameIn.c_str(), true, new
StreamTransformationFilter( e1, new FileSink(cout)));
//else
FileSource( inFile, true, new
StreamTransformationFilter( e1, new FileSink(outFile)));
err= false;
return;
} catch (Exception& e) {
errMsg = e.GetWhat();
err = true;
return;
}
}


static void DecryptFileAES(istream& inFile, ostream& outFile, string
key, string iv, bool &err, string &errMsg) {
// will encrypt the file at filenameIn to filenameOut using
AES
// WARNING: The correct iv MUST be provided
// key and iv can be hex or binary

// convert the key and iv
key = HexDecode(key);
iv = HexDecode(iv);

try {
// Set up the encrypter

CBC_Mode< CryptoPP::AES>::Decryption d ( (byte
*)key.c_str(), key.length(), (byte *)iv.c_str() );
// encrypt
//if (filenameOut == "cout")
// FileSource( filenameIn.c_str(), true, new
StreamTransformationFilter( d, new FileSink(cout)));
//else
FileSource( inFile, true, new
StreamTransformationFilter( d, new FileSink(outFile)));
err= false;
return;
} catch (Exception& e) {
errMsg = e.GetWhat();
err = true;
return;
}
}



int main (int argc, char * const argv[])
{
bool err;
string errMsg;

AutoSeededRandomPool rng;


string key3(AES::DEFAULT_KEYLENGTH, 0);
string iv3(AES::BLOCKSIZE, 0);// this is the Initialization
Vecktor

//Create a random key as well as a random IV with default sizes (16)
rng.GenerateBlock((unsigned char*)key3.c_str(),
AES::DEFAULT_KEYLENGTH);
rng.GenerateBlock((unsigned char*)iv3.c_str(), AES::BLOCKSIZE);



// Now encrypt it with the MR methods
// First open the infile
ifstream infile("C:\\Qt\\abc.mp3", ios::binary); // always open
your files in binary mode!

// Now the outfile, this can be any outstream, but we'll save to
disk first
ofstream outfile("C:\\Qt\\example.txtcrypt", ios::binary);
ofstream outfile2("C:\\Qt\\abc2.mp3",ios::binary);

// encrypt it!
EncryptFileAES(infile,outfile,key3,iv3,err,errMsg);
//BasicCryptoPPWrap::MREncryptFileAES(infile, outfile, key2, err,
errMsg);
if (err) {
cout << errMsg << "\n";
return -1;
}

infile.close();
outfile.close();

// delete the old text file
//remove("SecretSteakRecipe.txt");

// Now we'll decrypt, but do it to memory so we leave no trace!
stringstream outBuffer;
infile.open("C:\\Qt\\example.txtcrypt", ios::binary);

// Decrypt it!
DecryptFileAES(infile, outfile2, key3,iv3, err, errMsg);
if (err) {
cout << errMsg << "\n";
return -1;
}

// close and delete the encrypted file (you don't want me leaving
files all over your hard drive do you?)
infile.close();
outfile2.close();

}

// code ends

On Sep 11, 11:20 am, GrimReaper <udit.grimrea...@gmail.com> wrote:
> I am running qt 4.6,mingw compiler
> windows 7
> cryptopp 5.5.2 version
>
> The file was corrupted in a way that i decrypted that the image only
> top part of it was decrypted right(1/7th part of image form top
> recovered)(total image size7 kb) rest was blank
>
> on bigger images it corrupted
>
> I am not much in security i just wanted to pass infile outfile
> password and it should returned encrypted file and decvrypted file, i
> am trying to do that with aes , des ,triple des blowfish
>
> for aes
>
> i tried this link, its the code for aes file encryption and this is
> working very good with full decryptionhttp://swarmapps.wordpress.com/2009/11/24/a-simplification-wrapper-fo...
> ...
>
> read more »
Reply all
Reply to author
Forward
0 new messages