Hello i am using AES to encrypt/decrypt data/ pixel values.. saved in a file myfile.txt and the AES encrypts tha data and writes the ciphertext in a file ciphertext.txt
When decrypting the data i am getting some of the pixel values decrypted correctly followed by garbage..

Code to open myfile.txt and save ciphertext to Ciphertext.txt file

char d;
	ifstream myfile1 ("myfile.txt");
	ofstream myfile3 ("Ciphertext.txt");
	
	myfile1.get(d);  //priming read

  while(!myfile1.eof())
{
	  for ( j=0; j<BC; j++)
	  for ( i=0; i < 4; i++)        
	  {
		  a[i][j] = d; // plaintext
		  //cout<<a[i][j]; // to chk how many plaintext is copied
		  myfile1.get(d);  //reads first element of next block
	  } 

		  Encrypt(a, rk);
		  counter1();
		
	  if (myfile3.is_open())
	  {
		  for(j=0; j< BC; j ++)
			  for ( i=0; i<4; i++)
				  myfile3<<a[i][j];
	  }   
	  else        
		cout << "Unable to open file";
  }	 
   	myfile3.close();
	myfile1.close();

Code to open Ciphertext.txt and save decrypted data to text.txt file

char buffer[4][4];
	char dxc;
	ifstream myfile4 ("Ciphertext.txt");
	ofstream myfile5 ("Text.txt");

	myfile4.get(dxc);  //priming read

  while(!myfile4.eof())
  {
	  for ( j=0; j<BC; j++)
	  for ( i=0; i < 4; i++)        
	  {
		  buffer[i][j]=dxc;
		  //a[i][j] = dxc; // plaintext
		  //cout<<a[i][j]; // to chk how many plaintext is copied
		  myfile4.get(dxc);  //reads first element of next block
	  }

	  for ( j=0; j<BC; j++)
	  for ( i=0; i < 4; i++)        
	  {
		  a[i][j] = buffer[i][j];

	  }
		  Decrypt(a, rk);
		  counter2();

		if (myfile5.is_open())
		{
		    for(j=0; j<BC; j ++)
			for ( i=0; i<4; i++)
			myfile5<<a[i][j];
		}   
		  else        
			  cout << "Unable to open file";
  }			 
  	myfile5.close();
	myfile4.close();

E.g:- pixel values im myfile.txt
-13224404 -14211046 -14605042 -13682410 -12298975 -11245015 -10322644 -9532112 -8609993 -7490750 -6240432 -5516455 -4990625 -4332695 -3675534 -3412107 -3082376 -2753413 -2687618 -2884997 -3082374 -3082628 -3345799 -3740555 -3675016 -3675013 -3675267 -3609474 -3412093 -3214714 -3017333 -2885749 -2557300 -2425716 -2622326 -2885500 -3082625 -3345797 -4069263 -4727191 -5319066 -6108833 -6766499 -7424678 -8609203 -9333176 -9925051 -10714820 -11240648 -11503818 -11635406 -11437774 -11437776 -11634903 -11503318 -11239892 -11503066 -11503066 -11503064 -11503318 -11503317 -11503317 -11503315 -11503315 -11109329 -11109329 -10978000 -10978000 -10912461 -10912461 -10715850 -10715850 -10847949 -10847949 -10782667 -10848460 -10914252 -10914252 -10849229 -10849227 -10782918 -10782916 -10848709 -10914502 -11046088 -11111881 -11177674 -11177674 -11506639 -11506639 -11506639 -11506639 -11440846 -11440846 -11440846 -11440846
-13158611 -14276582 -14670578 -13682410 -12364768 -11245015

Pixel values in text.txt
-13224404 -14211046 -14605042 -13682410 -12298975 -11245015 -10322644 -9532112 \Ó¶¬6Ewƒ›SÆû53yè

However, some of the encrypted text is the same as EOF and thus i cant read the text
that after it. What should i do?
How to remove the EOF character from the encrypted text...

Recommended Answers

All 57 Replies

Use binary mode to open files which deal with encrypted text.

That should solve the problem with the EOF char :)

P.S Refer to my reply to your mail.

If you get it working post the working program here :D

As I'd said privately, you don't want to change the EOF char in your ciphertext - that will corrupt the data.

In order to read in the file, without the EOF character halting the read, do so in a binary fashion. Grab 16 bytes, then place them in your 4x4 array. Life will be good.

Here's a sample of how to read in binary mode.

#include<iostream>
#include <fstream>
using namespace std;

int main( )
{
   fstream f;
   unsigned char buff[16];
   int i, j;

   f.open( "ciphertext.txt", ios::binary | ios::in );
   if( !f )
   {
      cout << "error opening file, quitting" << endl;
      return -1;
   }


   for( j = 0; j < 10; j++ ) //we just want to see a sample of the file
   {
      f.read( (char *)buff, 16 );
      for( i = 0; i < 16; i++ )
         cout << int ( buff[i] ) << " " ; //display ASCII values
      cout << endl;
   }


   return 0;
}

This will give you a dump of the ASCII values for the 160 bytes, and that should be enough for you to get past the at least the first occurrence EOF (decimal 26) character.

For reading the full file, control the loop as:

while( f.read( (char *)buff, 16 ) )

For this to work right, you must ensure your encoding process creates a file that is a multiple of 16 bytes in size.

Various subtleties, but 'EOF character' is not a good idiom to maintain.
http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1048865140&id=1043284351

Using EOF to find end of file is not what this thread is about. It's NOT about reading till EOF char is encountered, but how to get past the EOF character.

Contrary to your reference, there is an EOF character (check your neighborhood ASCII chart) and reading it in text mode will cause end of input. The OP has file of encrypted data which may happen to include the value that equates to the EOF character, and that's what's causing problems.

Using EOF to find end of file is not what this thread is about. It's NOT about reading till EOF char is encountered, but how to get past the EOF character.

Contrary to your reference, there is an EOF character (check your neighborhood ASCII chart) and reading it in text mode will cause end of input. The OP has file of encrypted data which may happen to include the value that equates to the EOF character, and that's what's causing problems.

File systems vary, there is absolutely no need for a file to contain an 'EOF character'. On a common system, a particular character in a file opened in text mode might be translated into a value that causes the eof signal to be raised.

This is not because an 'EOF character' exists, it is because a binary file is being examined in text mode. Blurring such subtleties by repeating 'EOF character' to me is a bit of a disservice.

If the file is opened in the correct mode for the input, then there is no need to watch out for things that aren't there.

Not disputing what you say, Dave.

It's a matter of what the OP's problem is here, and how I (and at least one other) have been trying to help him around it.

In short, he read in a plain text file, encrypts it, stores it back - a collection of bytes in the range 0-255.

He (attempted) to open the encrypted file, as a text file, and read it back for decryption. This fails when a byte valued 26 (decimal) is encountered. We're trying to get the point across that, at least for reading the ciphertext, he must do so in binary mode. The resulting plaintext can be written back in text mode, assuming correct decryption.

P.S Refer to my reply to your mail.

As I'd said privately....

No one should be answering private requests for help. That's because no one should be asking for private help. Help is what these forums are for. Keep all questions and answers in the forums, please.

Not disputing what you say, Dave.

It's a matter of what the OP's problem is here, and how I (and at least one other) have been trying to help him around it.

And Dave is trying to clear up misinformation being passed to the OP. Though not directly related to his problem, telling him there's an EOF character is teaching him 'bad grammar' which he will pass on to the next person. So don't argue with Dave. He's trying to help, too.

char d;
	ifstream myfile1 ("myfile.txt");
	ofstream myfile3  ("ciphertext.txt");

	myfile1.get(d);  //priming read

  while(!myfile1.eof())
{
	  for ( j=0; j<BC; j++)
	  for ( i=0; i < 4; i++)        
	  {
		  a[i][j] = d; // plaintext
		  //cout<<a[i][j]; // to chk how many plaintext is copied
		  myfile1.get(d);  //reads first element of next block
	 }
		  Encrypt(a, rk);
		  counter1();
	
	  if (myfile3.is_open())
	  {
		  for(j=0; j< BC; j ++)
			  for ( i=0; i<4; i++)
				  myfile3<<a[i][j];
	  }   
	  else        
		cout << "Unable to open file";
  }  
   	myfile3.close();
	myfile1.close();
	  
	unsigned char buff[4][4];
	fstream myfile4;
	myfile4.open( "ciphertext.txt", ios::binary | ios::in );
	if( !myfile4 )
	{
      cout << "error opening file, quitting" << endl;
      return -1;
	}
	ofstream myfile5 ("Text.txt");	
 
	  while(myfile4.read( (char *)buff, 16 ))
	  {
                    for( i = 0; i < 4; i++ )
		  for( j = 0; j < 4; j++ )
                               buff[i][j];

	  for ( j=0; j<BC; j++)
	  for ( i=0; i < 4; i++)        
	  {
		  a[i][j] = buff[i][j];

	  }	
		  Decrypt(a, rk);
		  counter2();

	if (myfile5.is_open())
		{
		    for(j=0; j<BC; j ++)
			for ( i=0; i<4; i++)
			myfile5<<a[i][j];
		}   
		  else        
			  cout << "Unable to open file";
  }		 
  	myfile5.close();
	myfile4.close();

Hello i am getting an error message, file cannot be open, quitting...
The code that Vmanes sent in the prevoius post is working in the main function and retrieving in binary...
I have modified the code in the aes main program and its not opening the file cipheretxt.txt to read .... please help me out how to solve this poblem...

From the code given, I don't see any reason the file open action should be failing. Can you step through the program and after the point at which ciphertext.txt should have been written, verify that it in fact exists?

Once it does open, I think you'll find the decryption will not work right. In all your 4x4 array accesses, you've done them in column major fashion, that is, working down a column, then move to the next column. Reading directly into the the buff array will store in a row major fashion, the natural way that C/C++ work. Your code in lines 43-46 does nothing.

To store from the buff to array a, in the order in which you've previously worked, you need to copy rows to columns.

for ( j=0; j<BC; j++)
     for ( i=0; i < 4; i++)
    {
          a[i][j] = buff[j][i];
     }

Hello,
I am forwarding the codes in a zip file...I tried to debug the code in the main function so as to open the file ciphertext.txt in binary but still i am getting error messages...
The file cannot be opened...

error opening file, quitting

Please help me out how to solve this problem....

Zoinks! The ugly stepchild C/C++ nether-language circa 1995!

When I make necessary tweaks to compile, I got this.

128

--- Advanced Encryption Standard ---


Enter the length of Key(128, 192 or 256 only):

*********** AES Encryption using 128 bits **********

Key : 1111111111111111

----- AES Encryption Time for 1 Operation -----

Key Expansion Time : 0.000010 seconds.

AddRoundKey Time : 0.103023 seconds.

SubBytes Time : 0.083792 seconds.

ShiftRow Time : 0.097528 seconds.

MixColunms Time : 0.135990 seconds.

Encrytion Time : 0.420333 seconds.

Number of plaintext blocks of 16 bytes created: 4917

*********** AES Decryption using 128 bits **********

Key : 1111111111111111

----- Average AES Decryption Time for 1 Operation -----

Key Expansion Time : 0.000010 seconds.

AddRoundKey Time : 0.093787 seconds.

Inverse SubBytes Time : 0.096546 seconds.

Inverse ShiftRow Time : 0.096546 seconds.

Inverse MixColunms Time : 0.173782 seconds.

Decrytion Time : 0.460661 seconds.

Number of plaintext blocks of 16 bytes created: 4937


End of the program

Which software are you using to test the codes...
I am using visual c++ 6.0 on windows Xp..
Still getting error messages....
Have u made any modifications in the code... to run it..

I was minimally invasive, choosing merely to #include <iostream> instead of the nonstandard #include<iostream.h>. And I looked the other way on a few warnings.

I built with Code::Blocks' gcc. MSVC6 is one to ditch when you can find anything better, and you can. For free. Very easily. Even to another MS product. I'd recommend doing so with no reservations.

Thanks Dave Sinkula... Thats works...
But now i have my text decrypted in binary, I want the files plaintext.txt and text.txt the same
That is how to convert the binary encrypted text in char....
Also the program counts the number of 16 bytes block being created for encryption and decryption...But the number of encrypted and decrypted blocks created is not the same..
The number of decrypted blocks is more than the encrypted one for 128/192/256 keys..
Can anyone help me out...

Plaintext or ciphertext, open both as binary and process them thusly.

Yes, i have opened both as binary for encryption and decryption

fstream myfile1;
	myfile1.open( "plaintext.txt", ios::binary | ios::in );
fstream myfile4;
	myfile4.open( "ciphertext.txt", ios::binary | ios::in );

Still the files plaintext.txt and cipheretxt.txt not the same...

Well I haven't really been digging too deep, but I'm just not a fan of the eof() loop control -- as I'm sure you may have gathered. I prefer to instead look for a successful read before continuing with data that may or may not have been read. Maybe such an approach can be fruitful.

Another thing I see in glancing is the input of a plain char . When reading a bag of bytes as bytes, I always prefer unsigned char . This may not be a magic bullet either.

Perhaps later on I may have time to dwell if you haven't killed your bugs yet.

Hello i think the data has been corrupted that is why I am getting the text in encrypted form now... How can i solve this problem.... I have open the file in binary for decryption...
Is there another way to solve this problem instead of using files...

Ok so 1 method to solve this is to skip or delete the EOF character when reading the plaintext.txt before encryption...
How can this be done...
Please help me out how we can solve this problem...

Is there another way to solve this problem instead of using files...

Of course -- just store the encrypted data in memory. But of course when your program ends to does that data :)

Ok so 1 method to solve this is to skip or delete the EOF character when reading the plaintext.txt before encryption...
How can this be done...
Please help me out how we can solve this problem...

Perhaps try substituting a different encryption/decryption method temporarily to see whether or not the problem is within or without. The only minute bit I can offer in this direction is this -- but for the purpose of seeing whether or not the input and output files have the same size. Then again, I don't know whether your current method does padding.

But the idea with this is merely trying to isolate the bug(s): file handling or encryption algorithm. FWIW.

No there is no padding in the codes...
There is no way to solve the problem using files tried all the methods that have been suggested in the forum till now...

Ah. I'm seeing a likely culprit now.

for ( j=0; j<BC; j++ )
            for ( i=0; i < 4; i++ )
            {
               a[i][j] = d; // plaintext
               myfile1.get(d);  //reads first element of next block
            }

No test for a successful read.

[edit]The particular thing that caught my eye was a directory listing.

78,672 ciphertext.txt
78,661 plaintext.txt

To me this says that you may keep reading non-existent data.

[aside]This kinda thing is pretty much in the ballpark of why I dislike the "read to eof" idiom of input gathering.[/aside]

please help me out how to solve this poblem...

Please help me out how to solve this problem....

Can anyone help me out...

Please help me out how we can solve this problem...

Jeez! Stop begging! Aren't we trying to help you? :icon_rolleyes:

[edit]The particular thing that caught my eye was a directory listing.
To me this says that you may keep reading non-existent data.

[aside]This kinda thing is pretty much in the ballpark of why I dislike the "read to eof" idiom of input gathering.[/aside]

Dave is referring to the line while(!myfile1.eof()) in your code. See this for an explanation why it's a bad thing to use -- feof() and .eof() are identical.

And after you fix the .eof() , maybe it's time to post your current code. I assume you've made changes.

I have remove the while(!eof()) and open the file ciphertxt.txt in binary still the decryption does not work well...
I am posting the codes...

This is opening in binary mode?

ifstream myfile1 ("myfile.txt");
	ofstream myfile3  ("ciphertext.txt");

The file sizes seem quite a bit off:

78,961 ciphertext.txt
78,661 myfile.txt
78,661 plaintext.txt
79,245 Text.txt

I do this:

ifstream myfile1 ("myfile.txt", ios::binary);
	ofstream myfile3  ("ciphertext.txt", ios::binary);

The file sizes look a lot closer to what I would expect:

78,656 ciphertext.txt
78,661 myfile.txt
78,661 plaintext.txt
78,656 Text.txt

The remaining difference I speculate has to do with the code here:

while(myfile1.read( (char *)buff, 16 ) != NULL)

How is a partial buffer read handled?

[edit]Ah, http://dinkumware.com/manuals/?manual=compleat&Search=read&page=istream.html#basic_istream::read

Thanks Dave,
The code is encrypting and decrypting correctly... but just a small problem with the last pixel value is -11109 instead of -11109576
What may have caused this problem..

[Speculating...]In this example you are reading 16 byte chunks. This goes fine and dandy until the end of the file. There, the last read obtains 5 bytes and the code goes ahead and process 16 bytes. The leftover 11 bytes were likely from the previous read.

I think you need to handle this situation as a special case, different from the 'blocks of 16' processing.

So I need to do a padding i think for the 16 bytes....of data being encrypted and decrypted
How can this be solved..

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.