Как я могу защитить свои сохраненные данные от случайного взлома?

32

Какие есть варианты безопасного сохранения игровых данных? Я заинтересован в решениях, специально предназначенных для C ++.

Я ищу что-то быстрое и простое в использовании. Я беспокоюсь только о хранении простой информации, такой как

  • Какие уровни есть и не разблокированы

  • Оценка пользователя для каждого уровня

Мне снова любопытно узнать, что можно использовать, какие-нибудь хорошие библиотеки, которые дают мне хорошие, безопасные файлы с игровыми данными, с которыми обычный игрок не может связываться.

Я только что нашел это здесь, которое выглядит очень хорошо, но было бы здорово получить некоторые мнения о потенциальных других библиотеках / вариантах там.

dan369
источник
5
Зачем вам безопасность? Если игрок хочет обмануть, чтобы разблокировать уровень, отредактировав сохранение, потому что он застрял, почему бы просто не позволить ему это сделать?
Адам
2
что ж, игра, надеюсь, выйдет на IndieCity.com, у них есть собственная система достижений. Я хочу основать лишь несколько достижений на победе над определенными уровнями, содержащими боссов. Игрок не сможет обмануть свой путь, чтобы разблокировать эти достижения. Это против правил "CAP", как они называются. Поэтому мне нужно иметь какую-то форму меры безопасности, ничего особенного, только чтобы не дать случайному игроку изменить данные
dan369
1
Возможно, стоит сказать IndieCity.com, что для этого требования есть ограничения, поскольку вы не можете защитить сохраненную игру, если сохраненная игра не находится на вашем собственном сервере.
Kylotan

Ответы:

24

сначала скажем, так как у вас есть очень простой файл сохранения, вы можете использовать текстовый файл.

одна из самых простых идей - использовать ключ строки для блокировки / разблокировки данных:

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

но после небольшого поиска в Google я нашел эти ссылки, которые могут быть полезны:

Редактировать:

Основываясь на том, что подписанный символ является «неопределенным поведением», как упомянул @ v.oddou, я думаю, что использование XOR или приведение к неподписанному символу приведет к более безопасному / более кросс-платформенному коду. что-то вроде этого:

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
источник
это похоже на хороший маленький метод :), просто достаточно для моих целей. Мне любопытно задать еще один вопрос здесь, с точки зрения «ключа», что является приемлемым ключом? Могу ли я передать что-нибудь, например длинную строку?
dan369
И вы знаете, я думаю, что я просто собираюсь пойти с этим, это именно то, что я хотел. Простой и удобный в использовании, и ничего особенного :).
dan369
2
@Danran да, для ключа приемлема любая вещь, это может быть строка из одного символа, в результате чего получится нечто вроде шифра Цезаря или любая другая фраза любой другой длины, которая вам нравится. Вы также можете использовать какой-то другой алгоритм для шифрования позиций данных, например. меняйте значения в четных и нечетных позициях.
Ali1S232
Я предлагаю вам использовать XORвместо увеличения / уменьшения, так как вы можете получить поврежденные данные, если превысите границы типа данных, с которыми имеете дело ( charя полагаю)
bummzack
2
Это не имеет значения, используете ли вы xor, или увеличиваете / уменьшаете, восстанавливает данные. обратите внимание, что при увеличении числа родов переполнение, последующее уменьшение также приведет к снижению.
Ali1S232
24

Ничто не может считаться защищенной клиентской стороной; всякий, кто говорит, что это так, лжет.

Вы можете использовать любой метод шифрования и шифрования, который вы хотите, но, поскольку клиент также должен иметь возможность декодировать его, и пользователь имеет доступ к самому клиенту, если он достаточно изобретателен, у него будет доступ к ключу / алгоритму дешифрования.

Вы можете только добавить слои раздражения тому, кто хочет взломать его, но если у вас будет достаточно времени, он будет взломан , и вы ничего не можете с этим поделать.

о0' .
источник
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
источник
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
источник
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
источник