¿Cómo puedo proteger mis datos guardados del pirateo casual?

32

¿Qué opciones hay para guardar los datos del juego de manera segura? Estoy interesado en soluciones diseñadas específicamente para C ++.

Estoy buscando algo que sea rápido y fácil de usar. Solo me preocupa almacenar información simple como

  • Qué niveles están y no están desbloqueados

  • La puntuación del usuario para cada nivel

Tengo curiosidad nuevamente por saber qué hay para usar, cualquier buena biblioteca para usar que me brinde archivos de datos de juego seguros y agradables con los que el jugador promedio no pueda meterse.

Acabo de encontrar esto aquí, que se ve muy bien, pero sería genial obtener algunas opiniones sobre otras posibles bibliotecas / opciones.

dan369
fuente
55
¿Por qué requieren la seguridad? Si un jugador quiere hacer trampa para desbloquear un nivel editando el guardado porque se atascó, ¿por qué no dejarlo hacerlo?
Adam
2
bueno, es de esperar que el juego suba en IndieCity.com, tienen su propio sistema de logros para usar. Quiero basar solo unos pocos logros en derrotar ciertos niveles que contienen jefes. Hacer que el jugador sea capaz de engañar para desbloquear estos logros no está permitido. Está en contra de las reglas "CAP" como se les llama. Así que necesito tener alguna forma de medida de seguridad, nada sofisticado, pero solo para evitar que el jugador casual altere los datos
dan369
1
Puede valer la pena decirle a IndieCity.com que hay límites para ese requisito, ya que es imposible para usted asegurar una partida guardada a menos que la partida guardada permanezca en su propio servidor.
Kylotan

Respuestas:

24

Primero, digamos que ya que tiene un archivo de guardado muy simple, puede usar un archivo de texto.

Una de las ideas más simples es usar una tecla de cadena para bloquear / desbloquear datos:

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()];
}

pero después de una pequeña búsqueda en google encontré estos enlaces, que pueden ser útiles:

Editar:

Basado en que char firmado es "Comportamiento indefinido" como @ v.oddou mencionó, supongo que usar XOR o convertir a char sin firmar dará como resultado un código más seguro / multiplataforma. algo como esto:

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
fuente
este parece un pequeño y agradable método :), lo suficiente para mis propósitos. Tengo curiosidad por hacer una pregunta más aquí, en términos de una "clave", ¿qué es una clave aceptable? ¿Puedo pasar algo, es decir, una cadena larga?
dan369
Y sabes, creo que voy a seguir con esto, es exactamente lo que quería. Simple y fácil de usar, y nada demasiado elegante :).
dan369
2
@Danran, sí, todo es aceptable para la clave, puede ser una cadena de un carácter que dará como resultado un cifrado César o cualquier otra frase con cualquier otra longitud que desee. También puede utilizar algún otro algoritmo para codificar las posiciones de datos, por ejemplo. intercambiar valores en posiciones pares e impares.
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'.
fuente
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
fuente
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
fuente
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
fuente