Trouble with binary files

HI,

I'm using AES encryption. The encrypted text is then saved into a binary file. And elsewhere, that file is opened and the text decrypted. Pretty standard procedure..

However, when deserializing the text from the binary file, I can't get it properly decrypted. Here's the code:

input part:

1
2
3
4
5
6
7
unsigned char* ciphertext = NULL;

//AES encryption text.....

    ofstream file("c:\\Lic.bin", ios::out | ios::app | ios::binary);
	file.write(reinterpret_cast<char*>(ciphertext),                   strlen(reinterpret_cast<char*>(ciphertext)));
	file.close();


output part:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
unsigned char* ciphertext = NULL;
ifstream fileCode("c:\\Lic.bin");

	fileCode.seekg (0, ios::end);
	lengthLicenseFile = fileCode.tellg();
	fileCode.seekg (0, ios::beg);

	if(fileCode.is_open())
	{
		ciphertext = new unsigned char[lengthLicenseFile];
		while(!fileCode.eof())
		{
			fileCode.read((char *)ciphertext, lengthLicenseFile);
		}
			
		fileCode.close();
	}


ciphertext is the result of an AES encryption, and when I do the encrypt/decrypt process on the same class to test it, works perfectly. But when I encrypt/decrypt on different programs passing the encrypted value with a binary file, the value gets corrupted.

Any ideas?

Thanks!
Last edited on
Is the cythertext a null terminated string or is it a fixed length block of memory?
It is a fixed length block of memory. This is the full code of the input part:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
byte* ciphertext = NULL, *recovered = NULL;

	WinAES aes;

	aes.SetKeyWithIv( key, 16, iv, 16);

    ZeroMemory( key, 16 );

    size_t psize=0, csize=0, rsize=0;

    psize = strlen( buffTextToEncrypt ) + 1;
    if( aes.MaxCipherTextSize( psize, csize ) ) {
        ciphertext = new byte[ csize ];
    }

    if( !aes.Encrypt( (byte*)buffTextToEncrypt, psize, ciphertext, csize ) ) {
        cerr << "Failed to encrypt plain text" << endl;
    }

ofstream file("c:\\Lic.bin", ios::out | ios::app | ios::binary);
	file.write(reinterpret_cast<char*>(ciphertext),                   strlen(reinterpret_cast<char*>(ciphertext)));
	file.close();
strlen returns the length of a null terminated string. If Encrypt() doesn't return such string (which is very likely I think), then strlen won't work as expected.
Determine the length of the string some other way.
ifstream fileCode("c:\\Lic.bin");

You should probably open your binary file in binary mode.
I've rewritten the code in a shorter project in an effort of seeking the problem more efficiently. I'm not really sure now if the problem is within the binary file though..


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

    if( !aes.Encrypt( (unsigned char*)plaintext, psize, ciphertext1, csize ) ) {
        cerr << "Failed to encrypt plain text" << endl;
    }
	
	ofstream file(fileNameCode, ios::out | ios::app | ios::binary);
	file.write(reinterpret_cast<char*>(ciphertext1), strlen(reinterpret_cast<char*>(ciphertext1)));
	file.close();


	ifstream fileCode(fileNameCode, ios::out | ios::app | ios::binary);

	fileCode.seekg (0, ios::end);
	lengthLicenseFile = fileCode.tellg();
	fileCode.seekg (0, ios::beg);
	
	
	if(fileCode.is_open())
	{
		ciphertext = new unsigned char[lengthLicenseFile];
		while(!fileCode.eof())
		{
			fileCode.read(reinterpret_cast<char*>ciphertext, lengthLicenseFile);
		}
			
		fileCode.close();
	}

    if( aes.MaxPlainTextSize( csize, rsize ) ) {
        recovered = new byte[ rsize ];
    }

    if( !aes.Decrypt( ciphertext3, csize, recovered, rsize ) ) {
        cerr << "Failed to decrypt cipher text" << endl;
    }


First I encrypt a text into ciphertext1
I serialize the value within a file
I deserialize that same value into ciphertext.
After the deserialization, ciphertext has a length of 144

ciphertext1 and ciphertext are unsigned char

The problem is that lengthLicenseFile and ciphertext1 have the same length, 131. However, ciphertext has a length of 144, with this symbols áýýýý««««««««þ.

I'm lost here.

Thanks
Last edited on
ifstream fileCode(fileNameCode, ios::out | ios::app | ios::binary);

Seriously?

Why are you looping on eof?

Same question as before. Does strlen(ciphertext1) return 144 or does it encounter a nul character in the encrypted text and return a value you weren't expecting? (Say around character 131?)

Why are you using reinterpret_cast for a static_cast job?

strlen(ciphertext1) return 131.

I have changed the reinterpret_cast and eof, they were unappropiate for this but they were not the cause, it is still happening
Alright. I misread your original post. I thought you were losing characters, not gaining them.

This is what's happening: Your orginal data is delimited by a '\0' and doesn't have any of those in the 'body' of the string. However, strlen returns the length of the string without the final '\0', so when you write it, you don't write the nul terminating character.

Then when you read it in, you must try to use strlen (or some other function that depends on the string being nul-terminated) which results in you accessing memory you don't own, because the terminating nul character is not present.

The simplest fix would be to change line 7 in the last code you posted to specify the length as strlen(...)+1
Last edited on
That worked out. Thanks!
Topic archived. No new replies allowed.