Como posso proteger meus dados salvos de hackers casuais?

32

Que opções existem para salvar dados de jogos de maneira segura? Estou interessado em soluções especificamente adaptadas para C ++.

Estou procurando por algo que seja rápido e fácil de usar. Estou preocupado apenas em armazenar informações simples, como

  • Quais níveis são e não são desbloqueados

  • A pontuação do usuário para cada nível

Estou curioso novamente para saber o que há para usar, quaisquer boas bibliotecas para usar que me proporcionem arquivos de dados de jogos agradáveis ​​e seguros que os jogadores comuns não podem mexer.

Acabei de encontrar isso aqui, que parece muito bom, mas seria ótimo obter algumas opiniões sobre outras possíveis bibliotecas / opções por aí.

dan369
fonte
5
Por que você precisa da segurança? Se um jogador quiser trapacear para desbloquear um nível, editando o save porque ficou preso, por que não deixá-lo fazer isso?
Adam
2
bem, espero que o jogo seja lançado no IndieCity.com, eles têm um sistema de conquistas para usar. Quero basear apenas algumas conquistas na derrota de certos níveis que contêm chefes. Não é permitido que o jogador trapaceie para conseguir essas conquistas. É contra as regras "CAP", como são chamadas. Então eu preciso ter algum tipo de medida de segurança no lugar, nada extravagante, mas apenas para parar o o jogador casual a partir de dados alterando
dan369
1
Pode valer a pena informar ao IndieCity.com que existem limites para esse requisito, pois é impossível garantir um jogo salvo, a menos que ele permaneça em seu próprio servidor.
Kylotan

Respostas:

24

primeiro, digamos que, como você tem um arquivo salvo muito simples, você pode usar um arquivo de texto.

uma das idéias mais simples é usar uma chave de cadeia para bloquear / desbloquear dados:

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

mas depois de uma pequena pesquisa no google, encontrei esses links, que podem ser úteis:

Editar:

Com base no char assinado como "Comportamento indefinido", como o @ v.oddou mencionou, acho que usar XOR ou converter para char não assinado resultará em um código mais seguro / de plataforma cruzada. algo assim:

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
fonte
este parece ser um bom método :), apenas o suficiente para meus propósitos. Estou curioso para fazer uma pergunta adicional aqui, em termos de uma "chave", o que é uma chave aceitável? Posso passar qualquer coisa, isto é, uma corda longa?
dan369
E você sabe, eu acho que vou concordar com isso, é exatamente o que eu queria. Simples e fácil de usar, e nada muito chique :).
dan369
2
@ Danran, sim, tudo é aceitável para a chave, pode ser uma string de um caractere que resultará em algo como a cifra de César ou qualquer outra frase com qualquer outro comprimento que você desejar. você também pode usar outro algoritmo para embaralhar as posições dos dados, por exemplo. trocar valores em posições pares e ímpares.
Ali1S232
Eu sugiro que você use XORem vez de aumentar / diminuir, como você pode acabar com dados corrompidos se você exceder os limites dos dados do tipo que você está lidando com ( chareu assumo)
bummzack
2
Realmente não importa, você usa xor ou incrementa / diminui, os dados são recuperados. Observe que, se o incremento de geração por excesso de transbordamento, a decodificação posterior também gerará subfluxo.
11111 Ali1S232
24

Nada pode ser considerado do lado do cliente seguro; quem lhe disser que está mentindo.

Você pode usar qualquer método de criptografia e codificação que desejar, mas como o cliente também deve ser capaz de decodificá-lo e o usuário tiver acesso ao próprio cliente, se tiver recursos suficientes, terá acesso à chave / algoritmo de descriptografia.

Você só pode adicionar camadas de aborrecimentos a alguém disposto a quebrá-lo, mas, com tempo suficiente, ele será quebrado e você não poderá fazer nada a respeito.

o0 '.
fonte
26
Enquanto o que você está dizendo é verdade, acho que o autor está ciente de que um hacker determinado provavelmente ainda pode entrar nisso, pois pediu explicitamente uma maneira de impedir o "hacking casual". : - \
loneboat
2
Exatamente, ciente de que um hacker, se determinado, poderia acessar facilmente os dados do meu jogo. Eu simplesmente não queria que o usuário médio / casual pudesse abrir os arquivos e começar a editá-los.
dan369
@ Danran: bom, eu não gosto muito disso, mas acho que faz sentido em alguns contextos. Não estou excluindo a resposta, porque acho importante ressaltar isso para as pessoas que estão lendo isso.
o0 '.
2
Além disso, se for considerado que vale a pena hackear alguém provavelmente fará com que seja possível hackear o usuário casual. Existem fóruns inteiros dedicados a isso.
Jesse Dorsey
@ Noctrine: uma reação ativa pode ajudar neste caso. fique atento à comunidade do seu jogo, quando alguma ferramenta de crack estiver disponível, mude a técnica de criptografia e libere um patch. esse patch pode ser obrigatório se o jogo tiver um componente online. é claro que nenhum jogador (e certamente não eu) gosta de ser forçado a atualizar as coisas em primeiro lugar, nem gosto de precisar estar conectado. (EA evil, simcity boo ...)
v.oddou
10

Você pode definitivamente deixar seu arquivo salvo sem criptografia, mas adicionar uma soma de verificação que é calculada através de todos os valores que você deseja "proteger".

O cracker, portanto, seria capaz de reproduzir novamente o hash (que você obviamente usará com sal adequado) e, portanto, terá um tempo feliz tentando reproduzir novamente.

Isso ainda não seria 100% seguro, mas provavelmente a melhor solução eficaz em termos de tempo.

Herr
fonte
2

Isso forneceu uma criptografia XOR simples:

#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;
}

E como usá-lo:

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;
}

A saída deste código é esta:

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

Aqui estão alguns programas (gratuitos de qualquer maneira) que podem ajudá-lo, ambos basicamente combinam todos os seus recursos em um único exe.

  • NBinder , agora um produto comercial, esta é uma versão antiga, mas funcional.

  • Enigma Virtual Box , outra ferramenta com recursos semelhantes.

TenaciousD
fonte