Comment puis-je protéger mes données de sauvegarde contre le piratage occasionnel?

32

Quelles sont les options pour sauvegarder les données de jeu de manière sécurisée? Je suis intéressé par les solutions spécialement conçues pour C ++.

Je cherche quelque chose qui soit rapide et facile à utiliser. Je ne suis préoccupé que par le stockage d'informations simples telles que

  • Quels niveaux sont et ne sont pas débloqués

  • Le score de l'utilisateur pour chaque niveau

Je suis à nouveau curieux de savoir ce qu'il y a à utiliser, toutes les bonnes bibliothèques à utiliser qui me donnent de beaux fichiers de données de jeu sécurisés que le joueur moyen ne peut pas jouer.

Je viens de trouver ceci ici qui a l'air très bien, mais ce serait bien d'avoir quelques opinions sur d'autres bibliothèques / options potentielles.

dan369
la source
5
Pourquoi avez-vous besoin de la sécurité? Si un joueur veut tricher pour déverrouiller un niveau en modifiant la sauvegarde parce qu'il s'est coincé, pourquoi ne pas le laisser le faire?
Adam
2
Espérons que le jeu va monter sur IndieCity.com, ils ont leur propre système de réalisation à utiliser. Je veux baser seulement quelques réalisations de vaincre certains niveaux contenant des boss. Il n'est pas autorisé de laisser le joueur capable de tromper sa façon de déverrouiller ces succès. Son contre les règles "CAP" comme on les appelle. J'ai donc besoin d'une mesure de sécurité en place, rien d'extraordinaire, mais juste pour empêcher le joueur occasionnel d'altérer ses données
dan369
1
Il serait peut-être intéressant de dire à IndieCity.com que cette exigence est limitée, car il vous est impossible de sécuriser une sauvegarde sauf si la sauvegarde reste sur votre propre serveur.
Kylotan

Réponses:

24

Tout d'abord, disons que puisque vous avez un fichier de sauvegarde très simple, vous pouvez utiliser un fichier texte.

Une des idées les plus simples consiste à utiliser une clé de chaîne pour verrouiller / déverrouiller des données:

void encrypt(string& data,string key)
{
    for(unsigned i=0;i<data.size();i++)
        data[i] += key[i%key.size()];
}

void decrypt(string& data,string key)
{
    for(unsigned i=0;i<data.size();i++)
        data[i] -= key[i%key.size()];
}

mais après une petite recherche sur Google, j'ai trouvé ces liens, qui pourraient être utiles:

Modifier:

Si le caractère signé correspond au "comportement non défini" indiqué par @ v.oddou, je suppose que l'utilisation de XOR ou la transposition sur un caractère non signé donneront lieu à un code plus sûr / multiplateforme. quelque chose comme ça:

void encrypt(string& data,string key)
{
    for(unsigned i=0;i<data.size();i++)
        data[i] ^= key[i%key.size()];
}

void decrypt(string& data,string key)
{
    for(unsigned i=0;i<data.size();i++)
        data[i] ^= key[i%key.size()];
}
Ali1S232
la source
cela semble être une jolie petite méthode :), juste ce qu'il me faut. Je suis curieux de poser une autre question ici, en termes de "clé", qu'est-ce qu'une clé acceptable? Puis-je passer n'importe quoi, c'est-à-dire une longue chaîne?
dan369
And you know, i think im just going to go with this, it's exactly what i wanted. Simple and easy to use, and nothing too fancy :).
dan369
2
@Danran yeah every thing is acceptable for the key, it can be a one char string which will result in something like Caesar cipher or any other phrase with any other length you like. you can also use some other algorithm to scramble data positions, eg. swap values in even and odd positions.
Ali1S232
I suggest you use XOR instead of increment/decrement, as you might end up with corrupt data if you exceed the bounds of the data-type you're dealing with (char I assume)
bummzack
2
It dons't really matter, either you use xor, or increment/decrements, data recovers. note that if incrementing generaees overflow, later decreament will also generate underflow.
Ali1S232
24

Nothing can be considered secure client side; anyone who tells you it is, is lying.

You can use any encryption and scramble method you want, but since the client must be also able to decode it, and the user has access to the client itself, if he is resourceful enough he'll have access to the decryption key / algorithm.

You can only add layers of annoyances to someone willing to crack it, but given enough time it will be cracked, and you can't do anything about that.

o0'.
la source
26
While what you're saying is true, I think the author is aware that a determined hacker could probably still get at it, since he explicitly asked for a way to prevent "casual hacking". :-\
loneboat
2
Exactly, well aware that a hacker if that determined could easily access my game data. I just didn't want the average/casual user to be able just to simple open up the files and start editing them.
dan369
@Danran: fine, I don't like that very much but I guess it makes sense in some contexts. I'm not deleting the answer because I think it is important to point this out to people reading this.
o0'.
2
Also, if it's deemed worth hacking someone will likely make it so that hacking it is possible by the casual user. There are entire forums dedicated to just that.
Jesse Dorsey
@Noctrine : an active reaction can help in this case. keep aware of the community around your game, when some crack tool is out in the open, change the encryption technique and release a patch. this patch can be made mandatory if the game has an online component. of course no player (and certainly not me) likes to be forced to update stuff at all in the first place, nor do I like to need to be connected. (EA evil, simcity boo...)
v.oddou
10

You can definitely leave your save file unencrypted but add a checksum that is calculated through all the values that you want to "guard".

The cracker would therefore be able to re-produce the hashing (which you off course will use with proper salt) and therefor will have a happy time trying to re-produce.

This would still not be %100 secure but, probably the best time effective solution.

Herr
la source
2

This provided some simple XOR encryption:

#include <iostream>

using namespace std;

string encryptDecrypt(string toEncrypt) {
    char key[3] = {'K', 'C', 'Q'}; //Any chars will work
    string output = toEncrypt;

    for (int i = 0; i < toEncrypt.size(); i++)
        output[i] = toEncrypt[i] ^ key[i % (sizeof(key) / sizeof(char))];

    return output;
}

And how to use it:

int main(int argc, const char * argv[])
{
    string encrypted = encryptDecrypt("kylewbanks.com");
    cout << "Encrypted:" << encrypted << "\n";

    string decrypted = encryptDecrypt(encrypted);
    cout << "Decrypted:" << decrypted << "\n";

    return 0;
}

The output of this code is this:

Encrypted: :=.43*-:8m2$.
Decrypted:kylewbanks.com
Lenard Arquin
la source
0

Here are a few programs (free ones anyway) that could help you, they both basically combine all you resources into a single exe.

  • NBinder, now a commercial product, this is an old but functional version.

  • Enigma Virtual Box, another tool with similar features.

TenaciousD
la source