Encrypt/decrypt int using xxtea and save the unsigned char using UserDefaults?

Hi!
The titel says it all!
Here is my code:

void wrapper::saveData(int num, const char* forKey)
{
	xxtea_long retLength = 0;
	unsigned char data[] = "hello";
	xxtea_long dataLength = sizeof(data);
	unsigned char key[] = "key";
	xxtea_long keyLength = sizeof(key);

	unsigned char *encryptedData =  xxtea_encrypt(data, dataLength, key, keyLength, &retLength);

	CCLOG("encrypted data: %s", encryptedData);

	unsigned char *decryptedData = xxtea_decrypt(encryptedData, retLength, key, keyLength, &retLength);

	CCLOG("decryped data: %s", decryptedData);


}

I want to encrypt the num and then save it using Userdefaults. How?

And then ofc in another function I want to decrypt the received data from UserDefaults?

@iQD I know you are into this. Could you help maybe?

Thanks!


you can add xxtea to it ,

std::string encrypteData(std::string data);
std::string decrypteData(std::string data);

just add the code and everything should work fine .

use:

UserDefaultEnc::getInstance()->getIntegerForKey("Level");
UserDefaultEnc::getInstance()->setIntegerForKey("Level",3);
1 Like

You have to convert the int to a char array by using sprintf. itoa is not supported by every compiler.
Unfortunately you have to cast types, as xxtea is dealing with unsigned char*, whereas the C functions are dealing with char*.

xxtea_long retLength = 0;
char data[sizeof(int)];
auto bytes = sprintf(data, "%d", num);
xxtea_long dataLength = sizeof(data);
unsigned char key[] = "key";
xxtea_long keyLength = sizeof(key);

unsigned char *encryptedData = xxtea_encrypt(reinterpret_cast<unsigned char*>(data), dataLength, key, keyLength, &retLength);

CCLOG("encrypted data: %s", encryptedData);

CCLOG("hashed data: %#8x", XXH32(dat, dataLength, seed));

// saving to UserDefault:
UserDefault::getInstance()->setStringForKey(forKey, std::string((char*)encryptedData));

In another function use this to receive data from UserDefault:

auto value = UserDefault::getInstance()->getStringForKey(forKey);
auto decryptedData = reinterpret_cast<unsigned char*>(const_cast<char*>(value.c_str()));
unsigned char *decryptedData = xxtea_decrypt(decryptedData, retLength, key, keyLength, &retLength);
CCLOG("decryped data: %s", decryptedData);

To UserDefaultEnc?
You still have to deal with casting issues, as it’s using std::string but xxtae is using POD types, not compatible with other C functions (unsigned char* vs. (const) char *). You have to do very nasty casting stuff.

The encrypteData and decrypteData functions of UserDefaultEnc are not encrypting data, they are just Base64 encoding and decoding functions!
UserDefaultEnc should maybe be called UserDefaultEncoding. The current implementation does not provide any encryption, so it might be a little confusing :smile:

Maybe it’s also a good/better idea, to modify UserDefault itself. providing encoding/hashing/encryption instead of implementing a wrapper.

@iQD Thank you for the tips . :slight_smile:

Thanks to you both! <3

If you just want to prevent your UserDefaults from modifying, you should concentrate on hashing your data. Addionally encryption won’t bring that much benefits to the table. Consider encryption to hide the real content from third parties like assets.

So I tried to implement your files into my project and called both get- and setInteger.
@Kotaiba
Now when I compile I get these errors":


Please help.

And @iQD what is your suggestion if I want to use a fast “encryption” of my stored data just so that people can’t edit the saved data directly. Is it to use xxtea and convert my int num to a char or this UserDefaultEnc?

Thanks guys!

I suggest to hash your data.
The encryption algorithms are working on byte arrays, so you always have to convert your data to this type.

Just hash your data, e.g. with xxHash. It’s not as secure and collision safe as other algorithms, because it’s a non-cryptographic hashing algorithm, but it’s sufficient for your purpose.
There is only a need for encryption, if you want to hide the content itself.

UserDefaultEnc does neither encrypt nor hash. It’s just encoding your data, which everyone can edit and modify.

How to use xxHash?

Thanks!

See my post.

CCLOG("hashed data: %#8x", XXH32(dat, dataLength, seed));

Just to get this clear then. I have to include xxHash and then I do not get it. An example, how can I hash the int num from the parameter and then save it using UserDefaults? THANKS!

I got lost when it went xxTea to xxHash… :slight_smile:

Anyway I found out that you have already answered my current question here: Any methods of storing, updating and retrieving game data! - #18 by iQD - C++ - Cocos Forums
@iQD Thanks so much for all your great help!