Link to home
Start Free TrialLog in
Avatar of Brad Brett
Brad BrettFlag for United States of America

asked on

XOR Encryption and Security

I am trying to create strong XOR encryption using C++ to encrypt files and then load the decrypted file into memory as LPCVOID

I want idea about a STRONG XOR encryption, since I know the following is easy to crack:
encryptedData = originalData ^ key;

Open in new window


I thought about something similar to the following:
encryptedData = originalData ^ key;
encryptedData ^= 52955258604;
encryptedData ^= 25435347522;
encryptedData ^= 25435443543;

Open in new window


However, I am not sure if that will be strong enough to the file very hard to crack.

Here is what I want:
1. Idea about a STRONG XOR Encryption and Decryption method.
2. How to load the decrypted data into LPCVOID for further use.
ASKER CERTIFIED SOLUTION
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Brad Brett

ASKER

I want to know if the following XOR encryption should be hard to crack or not:
encryptedData = originalData ^ key;
encryptedData ^= 52955258604;
encryptedData ^= 25435347522;
encryptedData ^= 25435443543;

Open in new window


Probably it's much harder than using:
encryptedData = originalData ^ key;

Open in new window


I also want to know how to load the decrypted data into LPCVOID

The library that you have provided looks great, but I see different types of encrpytions, which one would you suggest for file encryption.
With evilrix here (please no points for just backing him), but definitely go for something more efficiant than XOR. Sorry, let me rephrase it: Go for something efficiant. XOR isn't.
I want to know if the following XOR encryption should be hard to crack or not:
Probably it's much harder than using:
It is absolutely the same!! (And as mentioned not hard to crack at all) Doing those extra XOR operations is just like doing 1 XOR wih a different value for "key".


which one would you suggest for file encryption
As a starting point, I would probably look at AES.
If I want to create my own encryption class, what should I use instead of XOR to create a strong encryption class? (here I mean by creating it myself not using third parties)

What I want to do is to create UNKNOWN encryption and decryption method.

One important point is how to load the decrypted data into LPCVOID?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I agree with you about the point you mentioned and as in right now I am NOT a cryptography expert, but let me tell you this, I want the BASIC start of cryptography so I can use both my OWN and another cryptography class.

The main problem is the key will be in the C++ application and will be loaded into memory as a variable, so I guess someone COULD find out the key if they took a look over the application assembly.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I expected that comment!

I still think that If the private key is stored as a C++ variable, crackers could find it by viewing the assembly code!

The problem is the private key is NOT protected, it's a constant variable in C++, that's why I think they could find the key by viewing the application assembly.
If they can view the application code, then there isn't a big jump to them being able to work out any "custom" encryption method either.

Although if you are thinking that you need security to this sort of level, then it must be REALLY sensitive data, and therefore you probably should be protecting it in a very different way. ie. need a user to enter a password, or to have a smartcard, etc, etc.


Or are you just worried, that by having the key in the app code, that someone that has the app (and the time to dig for the key) could access another persons data controlled by your app. If so, and if each instance of your app is running in a secure enough environment, you could generate a random key when your program first runs and then store that (in an approriately authenticated/authorised location) on the machine for subsequent access.

It really depends on the exact scenarios that your app will be used in, and the environment within which it runs, etc.
They can't view the source code, but you can view the ASSEMBLY code for any EXE file.

It's not sensitive data, but it's important not to let others decrypt the data or change it.

What I am trying to do is to encrypt "graphic model files", so I can ONLY view them in DirectX, but not let anyone read from the model files or change/replace them.

Here is the deal:
// main.cpp
#include <string>

// Assuming I am using RSA encyption
string privateKey = "Key goes here";

Is that string secure enough If the end user only have the EXE file? (I doubt it)
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
An important question when it comes to encryption is how much money is involved.  If there is no money, you can do what you want and it won't matter.  No one will spend serious time trying to crack your code.  If there is more than $100 million involved, you need professional services because you will attract the interest of professional criminals.
encryptedData = originalData ^ key;
encryptedData ^= 52955258604;
encryptedData ^= 25435347522;
encryptedData ^= 25435443543;

Open in new window

is equivalent to
key ^= 52955420153;
encryptedData = originalData ^ key;
 

Open in new window

If you get serious, this search http://www.google.com/search?q=mathematical+basis+for+encryption will bring up a lot of papers about the math involved in encryption.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I heard about XOR One Time Pad, that's why I think it's possible to make strong encryption using XOR.

According to Wikipedia:
"the one-time pad (OTP) is a type of encryption which has been proven to be impossible to crack if used correctly"

http://en.wikipedia.org/wiki/One-time_pad
"If the key is truly random, as large as or greater than the plaintext, never reused in whole or part, and kept secret"
If the one-time pad is built using true encryption, that is true.  But XOR isn't even encryption, it is just a substitution code.  You computer can run thru all possible messages in slightly more time than a mouse click.  When people had to do these things by hand, substitution codes had a use because it could take a long time to decode a message.  With computers to process the possibilities, substitution codes are almost useless.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I don't know how else to say it and as I'm not in the habit of repeating myself to someone who isn't listening

@evilrix: You are not repeating what you say, neither you have to, I am not convinced that XOR is a kind of encryption, I KNOW encryption is actually algorithm and XOR is just a logic gate like (AND, OR, NOT, NOR, XNOR, etc...) it CAN be used in encryption as well, you don't have to convince me since I am just saying what I found out, you can't just judge what is going in my mind from comments I post here.

I am just mentioning WHAT I READ.

I will take a look over Crypto++

Regards,
I downloaded Crypto++, I am getting the following error after including dll.h and adding single line of code like "SHA1 sha1;":

"Cryptographic algorithms are disabled before the power-up self tests are performed."
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Where can I download the version that doesn't compliance with FIPS?

I downloaded version 5.6.1 from:
http://www.cryptopp.com/#download

I also want to know if someone can replace 'cryptopp.dll' with a modified version he compiled so the application call his OWN method and the person can get the encryption/decryption key.

Thanks,
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
After changing the line to "#define CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 1", I am getting an error while building:
PRJ0019: A tool returned an error code from "Performing Custom Build Step

I am using Windows 7 64-bit and of course I want the DLL to work on both x86 and x64.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I am using VS 2008.

The problem resolved now after changing CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 from 0 to 1 from the project settings.

Now, I am concerned If someone can compile a modified version of Crypto++ and replace the original one used by the application in the application folder to get the private key when the application give the private key to the modified DLL.
static unsigned char key[32] =
{
	0x4E, 0x46, 0xF8, 0xC5, 0x09, 0x2B, 0x29, 0xE2,
	0x9A, 0x97, 0x1A, 0x0C, 0xD1, 0xF6, 0x10, 0xFB,
	0x1F, 0x67, 0x63, 0xDF, 0x80, 0x7A, 0x7E, 0x70,
	0x96, 0x0D, 0x4C, 0xD3, 0x11, 0x8E, 0x60, 0x1A
};

Open in new window


Is it possible to have larger key than that one If I am using AES?
I think the key is too short.

Also If I don't know the original data length, how can I decrypt it?

// Decrypt
CFB_Mode<AES>::Decryption cfbDecryption(key, key.size(), iv);
cfbDecryption.ProcessData(result, result, data_length); // What If I dont know 'data_length'?
>> I think the key is too short
AES supports key sizes of 128, 192, or 256 bits. Trust me, that's plenty.
http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@evilrix:  To save time, can you provide methods to encrypt and decrypt Crypto++ AES no matter what it's the data length.

Using Crypto++, what I need is something similar to the following:
byte *Encrypt(byte *data, unsigned char key[])
{
         // Code goes here...

}

byte *Decrypt(byte *data, unsigned char key[])
{
         // Code goes here...
}

Open in new window

I can, but not tonight I'm afraid. It's just gone midnight here in the UK and I am just about to go to bed :)

If you're still struggling tomorrow I'll knock you up a quick demo.
No problem :)
Ok, I'm up and awake and should be able to find time to knock something up for you. Obviously I have to also to real life work so it probably won't be until a little later but I'll throw something together during the day :)
I appreciate your help and waiting...
I guess you forgot about the question! I don't have any problem with encryption, the problem is with decryption, maybe you can quickly mention the decryption method on any length of data (assuming I don't know the original data length) if you don't have time.

I think it will just take few lines of code to decrypt ;)
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I created a new project and ran the code and I am getting the following error:
Microsoft Visual Studio C Runtime Library has detected a fatal error.

Line:  _debugger_hook_dummy = 0;
File:   dbghook.c
The only time I've seen this problem is when you are linking to a release version of a library in a debug build (or vice-versa). I assure you the example code was fully tested before posting it. Check you are linking all the same types of DLLs (including the C Runtime).
I am still running into errors!

I fixed the first problem by using DLL Debug version, the code work well and I see the original text and the encrypted text printed on the console screen, however I get Debug assertion error before the console application ends.

---------------------------
Microsoft Visual C++ Debug Library
---------------------------
Debug Assertion Failed!

Program: h:\Evilrix AES Encryption\Debug\Evilrix AES Encryption.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp
Line: 52

Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Note, in particular, that I build with /MDd (Multi-threaded DLL - debug) for the C Runtime. I'd advise you ensure you build cryptocpp and your project with the same. In the release version you should use /MD (Multi-threaded DLL).

http://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx

But, essentially, if cryptocpp and your project are not built and linked with the same linker/code generation settings you can (and probably will) get weird and unexplainable runtime errors (such if the fun of using Visual Studio -- gcc does none of this nonsense!).
I am getting confused now, I am running into errors circle, the weird thing is that I don't get any error when I try to encrypt using: cfbEncryption.ProcessData(result, data, messageLen); and it encrypt and decrypt successfully

The following code work without any problem:
AutoSeededRandomPool rnd;

// Generate a random key
SecByteBlock key(AES::DEFAULT_KEYLENGTH);
rnd.GenerateBlock( key, key.size() );

// Generate a random IV
byte iv[AES::BLOCKSIZE];
rnd.GenerateBlock(iv, AES::BLOCKSIZE);

char plainText[] = "Hello! How are you.";
int messageLen = (int)strlen(plainText) + 1;

//////////////////////////////////////////////////////////////////////////
// Encrypt

CFB_Mode<AES>::Encryption cfbEncryption(key, key.size(), iv);
cfbEncryption.ProcessData((byte*)plainText, (byte*)plainText, messageLen);

//////////////////////////////////////////////////////////////////////////
// Decrypt

CFB_Mode<AES>::Decryption cfbDecryption(key, key.size(), iv);
cfbDecryption.ProcessData((byte*)plainText, (byte*)plainText, messageLen);

Open in new window


The above code is from:
http://www.cryptopp.com/wiki/Advanced_Encryption_Standard

However the code I got from here should be doing the SAME thing but I get assertion failure.

Now, I tried to set my project to have the same command line as in cryptopp project, I am getting another error!

Error      3      general error c1010070: Failed to load and parse the manifest. The system cannot find the file specified.      .\Debug\Evilrix AES Encryption.exe.intermediate.manifest      Evilrix AES Encryption

Maybe it would be easier if you can modify the code I posted for encryption and decryption so I can decrypt the data no matter what's the original data length.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Here is the problem:
int messageLen = (int)strlen(plainText) + 1;

Open in new window


I must pass that variable in order to decrypt! the problem is what if I don't know the original data length?

byte *Decrypt(byte *data, unsigned char key[])
{
   CFB_Mode<AES>::Decryption cfbDecryption(key, key.size(), iv);
   cfbDecryption.ProcessData((byte*)plainText, (byte*)plainText, messageLen);
   return plainText;
}
The length is the current data length not the original.
@evilrix: How about you upload the project that you have created?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@aikimark: Invalid zone!

This is Unmanaged C++ and NOT C++.NET, the question has nothing to do with .NET framework.
@evilrix: Well it's fine, but replacing C++ with C++.NET would confuse, since experts will think the question is about managed C++.
On a different note, I've just noticed you asked for a working project to play with. I must have missed that earlier. Apologies. You will probably need to edit the project file to correct the paths (or, create the same paths on your system)
>> What I am trying to do is to encrypt "graphic model files", so I can ONLY view them in DirectX, but not let anyone read from the model files or change/replace them.

Encryption is not a solution for everything and it certainly wont help you out here. There are tools like 3D Ripper DX that anyone can use to extract all models/geometry etc from the scenes that you create. The use of encryption is totally pointless for this purpose - a total waste of time and cpu.

You can encrypt a song but it can always be decoded from the sound card!
@ambience:

Let's say I have the following meshes:
car.x
tank.x
airstrike.x

How do I protect them from viewing/modifying? I think most known computer games encrypt mesh files.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@ambience: It's really easy to steal mesh file if it's not encrypted, at least it would be much harder if the mesh is encrypted.

Other things I need to encrypt are the game script, AI, etc...

If I left them without encryption, all the commercial game resources can be stolen so easily.

So, I don't think that commercial games just leave their mesh files unprotected and its so easy to get it by anyone.

Many people don't know how to steal the game meshes, while it's rendering while most others know how to steal a file!

You are saying things like: Hey, why would you lock your car? a thieve can steel it even if it's locked, why would you lock it!
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hmm ... I see the context changes with every comment ... but anyway.

1 - Most games have proprietary file formats for storing media, decoding the format in itself is a first line of defense against casual hackers. You'd also need custom convertors and loaders.

2 - Some games use custom file-systems inside a data file. For example the old Microsoft FoxBear DirectX sample implemented a read only filesystem inside a simple binary file. Such a file system is another level of defense because it makes it real hard to obtain files.

3 - As an added protection you can consider encryption. Enc can be on a per item level or just the container data file as in 2.

My personal inclination would be to implement 1 and 2 and think about 3 optionally. There is a sample on codeproject that gives a fully functional toolkit for creating a filesystem, hopefully there are toolkits for that.
@aikimark: How do I compile the meshes into resource file and then read the file later?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks guys! I really appreciate your help!