Faire.fichier txt illisible / non éditable

j'ai un programme qui sauve un peu .fichier txt avec un highscore:

 // Create a file to write to. 
string createHighscore = _higscore + Environment.NewLine;
File.WriteAllText(path, createText);

// Open the file to read from. 
string createHighscore = File.ReadAllText(path);

Le problème est que l'utilisateur peut modifier le fichier aussi simple que possible – avec une texteditor. Je veux donc rendre le fichier illisible / non éditable ou le chiffrer .

ma pensée était que je pouvais sauver les données dans un dossier de ressource, mais puis-je écrire dans un dossier de ressource? Ou l'enregistrer en tant que .dll, chiffrer / déchiffrer ou chercher une MD5 sum/de hachage.

36
demandé sur JJJ 2015-12-14 11:20:47

10 réponses

Vous ne pouvez pas empêcher l'utilisateur de modifier le fichier. C'est leur ordinateur, donc ils peuvent faire ce qu'ils veulent (c'est pourquoi toute la question de la GDN est... difficile).

depuis que vous avez dit que vous utilisez le fichier pour enregistrer un score élevé, vous avez un couple d'alternatives. Notez que, comme indiqué précédemment, aucune méthode n'empêchera un attaquant vraiment déterminé de modifier la valeur: depuis votre application est en cours d'exécution sur l'ordinateur de l'utilisateur, il peut tout simplement décompiler, regardez comment vous protégez la valeur (obtenir l'accès à tout secret utilisé dans le processus) et agir en conséquence. Mais si vous êtes prêt à décompiler une application, Découvrez le schéma de protection utilisé et trouver un script/patch pour le contourner seulement pour changer un nombre que vous pouvez voir, Eh bien, allez-y?

obscurcir le contenu

cela empêchera l'utilisateur d'éditer le fichier directement, mais cela ne les arrêtera pas dès que le l'algorithme d'obscurcissement est connu.

var plaintext = Encoding.UTF8.GetBytes("Hello, world.");
var encodedtext = Convert.ToBase64String(plaintext);

sauvegarder le texte chiffré dans le fichier, et inverser le processus lors de la lecture du fichier.

Signe le contenu

cela n'empêchera pas l'utilisateur d'éditer le fichier ou de voir son contenu (mais vous ne vous en souciez pas, un score élevé n'est pas secret) mais vous serez en mesure de détecter si l'Utilisateur a trafiqué avec lui.

var key = Encoding.UTF8.GetBytes("My secret key");
using (var algorithm = new HMACSHA512(key))
{
    var payload = Encoding.UTF8.GetBytes("Hello, world.");
    var binaryHash = algorithm.ComputeHash(payload);
    var stringHash = Convert.ToBase64String(binaryHash);
}

Enregistrer à la fois la charge utile et le hachage dans le fichier, puis lors de la lecture du fichier vérifier si le hachage enregistré correspond à un nouvellement calculé. Votre clé doit rester secrète.

chiffrer le contenu

tirer parti des bibliothèques cryptographiques de .NET pour chiffrer le contenu avant de le sauvegarder et de le déchiffrer lors de la lecture du fichier.

s'il vous plaît prendre l'exemple suivant avec un grain de sel et passer le temps nécessaire pour comprendre ce que tout fait avant mise en œuvre (oui, vous l'utiliserez pour une raison insignifiante, mais vous - ou quelqu'un d'autre - ne le fera peut-être pas). Portez une attention particulière à la façon dont vous produisez L'IV et la clé.

// The initialization vector MUST be changed every time a plaintext is encrypted.
// The initialization vector MUST NOT be reused a second time.
// The initialization vector CAN be saved along the ciphertext.
// See https://en.wikipedia.org/wiki/Initialization_vector for more information.
var iv = Convert.FromBase64String("9iAwvNddQvAAfLSJb+JG1A==");

// The encryption key CAN be the same for every encryption.
// The encryption key MUST NOT be saved along the ciphertext.
var key = Convert.FromBase64String("UN8/gxM+6fGD7CdAGLhgnrF0S35qQ88p+Sr9k1tzKpM=");

using (var algorithm = new AesManaged())
{
    algorithm.IV = iv;
    algorithm.Key = key;

    byte[] ciphertext;

    using (var memoryStream = new MemoryStream())
    {
        using (var encryptor = algorithm.CreateEncryptor())
        {
            using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
            {
                using (var streamWriter = new StreamWriter(cryptoStream))
                {
                    streamWriter.Write("MySuperSecretHighScore");
                }
            }
        }

        ciphertext = memoryStream.ToArray();
    }

    // Now you can serialize the ciphertext however you like.
    // Do remember to tag along the initialization vector,
    // otherwise you'll never be able to decrypt it.

    // In a real world implementation you should set algorithm.IV,
    // algorithm.Key and ciphertext, since this is an example we're
    // re-using the existing variables.
    using (var memoryStream = new MemoryStream(ciphertext))
    {
        using (var decryptor = algorithm.CreateDecryptor())
        {
            using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
            {
                using (var streamReader = new StreamReader(cryptoStream))
                {
                    // You have your "MySuperSecretHighScore" back.
                    var plaintext = streamReader.ReadToEnd();
                }
            }
        }
    }
}
59
répondu Albireo 2015-12-15 08:17:23

comme vous semblez être à la recherche d'un niveau de sécurité relativement bas, je vous recommande d'y aller pour un checksum. Quelques pseudo-codes:

string toWrite = score + "|" + md5(score+"myKey") + Environment.NewLine

si le score était de 100, il deviendrait

100 / a6b6b0a8e56e42d8dac51a4812def434

pour vous assurer que l'utilisateur ne s'est pas emporté avec le fichier, vous pouvez alors utiliser:

string[] split = readString().split("|");
if (split[1] != md5(split[0]+"myKey")){
     alert("No messing with the scores!");
}else{
     alert("Your score is "+split[0]);
}

Maintenant, bien sûr, dès que quelqu'un arrive à connaître votre ils peuvent faire n'importe quoi, mais je pense que c'est au-delà de la portée de cette question. Le même risque s'applique à tout mécanisme de chiffrement/déchiffrement.

L'un des problèmes, comme mentionné dans les commentaires ci-dessous, est qu'une fois que quelqu'un a compris votre clé (par le biais de la force brute), il pourrait la partager et tout le monde sera en mesure de changer très facilement leurs fichiers. Une façon de résoudre ce problème serait d'ajouter quelque chose de spécifique à l'ordinateur à la clé. Par exemple, le nom de l'utilisateur qui s'est connecté, a passé par md5.

string toWrite = score + "|" + md5(score+"myKey"+md5(System.username /**or so**/)) + Environment.NewLine

cela empêchera la clé d'être"simplement partagée".

12
répondu Daniël van den Berg 2015-12-16 07:04:20

probablement votre meilleur pari est de sécuriser l'ensemble du fichier en utilisant la sécurité NT standard et de modifier programmatiquement la liste de contrôle d'accès pour protéger l'ensemble du fichier d'être édité par des utilisateurs indésirables (à l'exception de celui qui imite votre propre application, bien sûr).

cryptographie ne peut pas aider ici parce que le fichier pourrait être encore modifiable en utilisant un éditeur de texte régulier (par exemple, notepad ) et l'utilisateur final peut corrompre le fichier en ajoutant juste un caractère supplémentaire (ou tomber de trop).

il y a une autre approche qui ne nécessite pas d'effort de programmation...

dites à vos utilisateurs qu'une fois qu'ils ont édité manuellement l'ensemble du fichier texte, ils ont perdu votre support. En fin de compte, si vous stockez ces données, c'est parce qu'elles sont requises par votre application. Le fait de le corrompre ou de faire la tâche risquée de l'éditer manuellement peut faire produire des erreurs à votre application.

une autre approche alternative ce qui implique un effort de programmation...

chaque fois que vous changez le fichier de votre application, vous pouvez calculer un MD5 ou SHA hachage et stocker dans un fichier séparé, et une fois que vous voulez lire ou écrire à nouveau, vous allez vérifier que le fichier entier produit le même hachage avant d'écrire à nouveau sur elle.

de Cette façon, l'utilisateur peut toujours modifier votre fichier manuellement, mais vous saurez quand ce inattendu comportement a été fait par l'utilisateur (sauf si l'utilisateur manuellement calcule le hachage chaque fois que le fichier est modifié...).

9
répondu Matías Fidemraizer 2015-12-14 08:43:49

quelque chose que je n'ai pas encore vu mentionné stocke le score élevé sur un tableau de leader en ligne. Évidemment, cette solution nécessite beaucoup plus de développement, mais puisque vous parlez d'un jeu, vous pourriez probablement faire usage d'un fournisseur tiers comme Steam, Origin, Uplay, ... Cela a l'avantage de chef de planches non seulement pour votre machine.

6
répondu Nzall 2015-12-14 13:30:40

vous ne pouvez pas enregistrer de données dans une dll, et à la fois le fichier de ressources et le fichier txt sont modifiables. On dirait que le cryptage est le seul moyen pour toi. Vous pouvez chiffrer la chaîne avant de l'enregistrer dans un fichier txt. Jetez un oeil à ce fil: chiffrer et déchiffrer une chaîne de caractères

5
répondu edgar.bjorntvedt 2017-05-23 12:26:06

vous pouvez sérialiser et deserialiser avec le cryptage avec CryptoStream :

Sérialiser fichier :

  • Créer et ouvrir des FileStream dans le mode d'écriture
  • créer Cryptostream et passer votre filestream
  • Écrire du contenu Cryptostream (crypter)

Désérialiser fichier :

  • créer et ouvrir FileStream en mode de lecture
  • créer Cryptostream et passer votre filestream
  • Lire à partir de Cryptostream (déchiffrer)

vous pouvez trouver des exemples et plus d'informations ici:

msdn.microsoft.com/en-us/library/system.security.cryptography.cryptostream.aspx

http://www.codeproject.com/Articles/6465/Using-CryptoStream-in-C

exemple:

byte[] key = { 1, 2, 3, 4, 5, 6, 7, 8 }; // Where to store these keys is the tricky part, 
byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 };
string path = @"C:\path\to.file";

DESCryptoServiceProvider des = new DESCryptoServiceProvider();

// Encryption and serialization
using (var fStream = new FileStream(path, FileMode.Create, FileAccess.Write))
using (var cryptoStream = new CryptoStream(fStream , des.CreateEncryptor(key, iv), CryptoStreamMode.Write))
{
    BinaryFormatter serializer = new BinaryFormatter();

    // This is where you serialize your data
    serializer.Serialize(cryptoStream, yourData);
}



// Decryption
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
using (var cryptoStream = new CryptoStream(fs, des.CreateDecryptor(key, iv), CryptoStreamMode.Read))
{
    BinaryFormatter serializer = new BinaryFormatter();

    // Deserialize your data from file
    yourDataType yourData = (yourDataType)serializer.Deserialize(cryptoStream);
}
2
répondu Fabjan 2015-12-14 09:18:09

solution Simple:

Pour atténuer les hackish utilisateur à changer le score, vous pouvez l'écrire comme un binaire, je suppose.

une autre solution:

" Ecrire les données dans une base de données SQLite?

2
répondu Eugene Krapivin 2015-12-14 18:51:55

vous pouvez nommer votre fichier comme quelque chose qui ne suggère pas qu'il a un tableau de score en elle (par exemple YourApp.dat) et crypter le contenu.

Les accepté de répondre ici contient le code pour le chiffrement et le déchiffrement du texte.

mise à Jour

Je suggère aussi d'utiliser Guid comme mot de passe pour le cryptage.

1
répondu Dmitri Trofimov 2017-05-23 12:02:40

vous ne pouvez pas écrire dans ressources , plus d'information existe dans cette réponse

la raison pour laquelle vous ne pouvez pas changer une chaîne de ressources à l'exécution, est parce que la ressource est compilé dans votre exécutable. Si vous inversez concevoir le compilé *.exe ou *.fichier dll, vous pouvez voir votre chaîne de caractères dans le code. Éditer un fichier exécutable déjà compilé est jamais une bonne idée (sauf si vous essayez pour le hacker), mais quand vous essayez pour le faire à partir du code des exécutables, il est tout simplement impossible, comme le le fichier est verrouillé pendant l'exécution.

  • vous pouvez ajouter attributs de lecture seulement ou attributs cachés à vos fichiers en utilisant fichier.SetAttributes , mais l'utilisateur peut toujours supprimer les attributs de windows et éditez le fichier.

un exemple:

File.SetAttributes(path, File.GetAttributes(path) | FileAttributes.Hidden);
  • une autre façon que je pourrais suggérer est de sauvegarder les données dans un fichier avec certains des extensions bizarres pour que l'utilisateur ne puisse pas les considérer comme modifiables ou fichier important. quelque chose comme ghf.ytr ( ne Peux pas penser à quelque chose plus bizarre maintenant! )
  • je suggère aussi de créer un fichier texte avec .dll extension et l'enregistrer dans l'un des dossiers de windows comme system32 . De cette façon, l'utilisateur sera vraiment difficile essayer de savoir où va l'information de score!
1
répondu Alex Jolig 2017-05-23 12:17:55

Voici un code pour faire un fichier texte non modifiable. de la même façon, vous utilisez cette technique pour la rendre non lisible, etc.

string pathfile = @"C:\Users\Public\Documents\Filepath.txt";

if (File.Exists(pathfile))
{
    File.Delete(pathfile);
}
if (!File.Exists(pathfile))
{
    using (FileStream fs = File.Create(pathfile))
    {
        Byte[] info = new UTF8Encoding(true).GetBytes("your text to be written to the file place here");

        FileSecurity fsec = File.GetAccessControl(pathfile);
        fsec.AddAccessRule(new FileSystemAccessRule("Everyone",
        FileSystemRights.WriteData, AccessControlType.Deny));
        File.SetAccessControl(pathfile, fsec);
    }
}
0
répondu Priyabrata biswal 2016-04-29 12:09:00