password encrypt decrypt crypto convert code c# encryption md5sum

c# - encrypt - Hacer que el archivo.txt sea ilegible/no editable



get hash md5 c# (10)

Tengo un programa que guarda un pequeño archivo .txt con una puntuación más alta:

// 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);

El problema es que el usuario puede editar el archivo lo más simple posible, con un texteditor. Así que quiero hacer que el archivo sea ilegible / no editable o encriptarlo .

Mi idea era que podía guardar los datos en un archivo de recursos, pero ¿puedo escribir en un archivo de recursos? O guárdelo como .dll, encripte / descifre o busque un MD5-sum / hash.


Algo que aún no he mencionado es almacenar el puntaje más alto en una tabla de clasificación en línea. Obviamente, esta solución requiere mucho más desarrollo, pero ya que estás hablando de un juego, probablemente puedas utilizar un proveedor de terceros como Steam, Origin, Uplay ... Esto tiene la ventaja adicional de que las tablas de clasificación no solo son para tu máquina


Aquí hay un código para hacer que un archivo de texto no sea editable. de la misma manera que usas esta técnica para que no sea legible, 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); } }


Como parece que busca una seguridad relativamente baja, realmente recomendaría ir a una suma de comprobación. Algunos pseudo-códigos:

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

Si el puntaje fuera 100, esto se convertiría

100 | a6b6b0a8e56e42d8dac51a4812def434

Para asegurarse de que el usuario no atempera con el archivo, puede usar:

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

Ahora, por supuesto, tan pronto como alguien conozca su clave pueden meterse con esto lo que quieran, pero lo consideraría más allá del alcance de esta pregunta. El mismo riesgo se aplica a cualquier mecanismo de cifrado / descifrado.

Uno de los problemas, como se menciona en los comentarios que figuran a continuación, es que una vez que alguien averigüe su clave (a través de la fuerza bruta), podrían compartirla y todos podrán cambiar fácilmente sus archivos. Una forma de resolver esto sería agregar algo específico de la computadora a la clave. Por ejemplo, el nombre del usuario que inició sesión corrió a través de md5.

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

Esto evitará que la clave sea "simplemente compartida".


No puede escribir en Recursos , existe más información en esta respuesta

La razón por la que no puede cambiar una cadena de recursos en tiempo de ejecución es porque el recurso está compilado en su ejecutable. Si realiza una ingeniería inversa del archivo compilado * .exe o * .dll, puede ver realmente su cadena en el código. La edición de un archivo ejecutable ya compilado nunca es una buena idea (a menos que intente hackearlo), pero cuando intenta hacerlo desde el código ejecutable, simplemente es imposible, ya que el archivo está bloqueado durante la ejecución.

  • Puede agregar atributos de Sólo lectura u Ocultos a sus archivos mediante File.SetAttributes , pero aún así el usuario puede eliminar los atributos de Windows y editar el archivo.

Un ejemplo:

File.SetAttributes(path, File.GetAttributes(path) | FileAttributes.Hidden);

  • Otra forma en que podría sugerir es guardar los datos en un archivo con algunas extensiones extrañas para que el usuario no pueda pensar que es un archivo editable o importante. algo así como ghf.ytrNo se me ghf.ytr nada más raro ahora! )
  • También sugiero hacer un archivo de texto con la extensión .dll y guardarlo en una de las carpetas de Windows como system32 . ¡De esta manera el usuario tendrá dificultades para tratar de averiguar a dónde va la información del puntaje!

No puede evitar que el usuario modifique el archivo. Es su computadora, por lo que pueden hacer lo que quieran (es por eso que todo el problema de DRM es ... difícil).

Como dijo que está usando el archivo para guardar un puntaje alto, tiene un par de alternativas. Tenga en cuenta que, como se dijo anteriormente, ningún método impedirá que un atacante realmente determinado altere el valor: dado que su aplicación se ejecuta en la computadora del usuario, simplemente puede descompilarla, ver cómo está protegiendo el valor (acceder a cualquier secreto utilizado en el proceso) y actuar en consecuencia. Pero si está dispuesto a descompilar una aplicación, descubra el esquema de protección utilizado y proponga un script / parche para evitarlo, solo para cambiar un número que solo usted puede ver, bueno, vaya a por él.

Ofuscar el contenido

Esto evitará que el usuario edite el archivo directamente, pero no los detendrá tan pronto como se conozca el algoritmo de ofuscación.

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

Guarde el texto cifrado en el archivo e invierta el proceso al leer el archivo.

Firme el contenido

Esto no evitará que el usuario edite el archivo o vea su contenido (pero no le importa, un puntaje alto no es secreto) pero podrá detectar si el usuario lo manipuló.

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

Guarde tanto la carga útil como el hash en el archivo, luego, cuando lea el archivo, verifique si el hash guardado coincide con uno recientemente calculado. Tu llave debe mantenerse en secreto.

Encripta el contenido

Aproveche las bibliotecas criptográficas de .NET para cifrar el contenido antes de guardarlo y descifrarlo al leer el archivo.

Por favor, tome el siguiente ejemplo con un grano de sal y dedique el tiempo necesario para comprender todo lo que hace antes de implementarlo (sí, lo usará por una razón trivial, pero es posible que usted o alguien más no lo haga en el futuro). Preste especial atención a cómo genera el IV y la clave.

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


No puede guardar datos en un dll, y tanto el archivo de recursos como el archivo de txt son editables. Parece que la encriptación es la única forma para ti. Puede encriptar la cadena antes de guardarla en un archivo txt. Eche un vistazo a este hilo: Encripte y descifre una cadena


Probablemente su mejor opción sea asegurar todo el archivo con la seguridad estándar de NT y cambiar de forma programática la lista de control de acceso para evitar que usuarios no deseados editen el archivo completo (excepto el que suplanta a su propia aplicación, por supuesto).

La criptografía no puede ayudar aquí porque el archivo puede ser editable usando un editor de texto normal (por ejemplo, un notepad ) y el usuario final puede dañar el archivo simplemente agregando un carácter adicional (o soltando uno).

Hay un enfoque alternativo que no implica esfuerzo de programación ...

Dígales a sus usuarios que una vez que hayan editado manualmente todo el archivo de texto, perderán su soporte. Al final del día, si está almacenando estos datos es porque su aplicación lo requiere. Corromperlo o realizar la arriesgada tarea de editarlo manualmente puede hacer que su aplicación produzca errores.

Otro enfoque alternativo que implica esfuerzo de programación ...

Siempre que cambie el archivo de su aplicación, puede calcular un hash MD5 o SHA y almacenarlo en un archivo separado, y una vez que quiera leerlo o escribirlo nuevamente, comprobará que todo el archivo produce el mismo hash antes. escribiendo de nuevo.

De esta forma, el usuario puede editar su archivo de forma manual, pero sabrá cuándo el usuario realizó este comportamiento inesperado (a menos que el usuario también lo compute manualmente siempre que se cambie el archivo ...).


Puede nombrar su archivo como algo que no sugiere que tenga una tabla de puntaje (ej. YourApp.dat) y encriptar los contenidos.

La respuesta aceptada here contiene el código para el cifrado y descifrado de texto.

Actualizar
También sugiero usar algunos Guid como contraseña para el cifrado.


Puedes serializarlo y deserializar con cifrado con CryptoStream :

Archivo serializado:

  • Crear y abrir FileStream en modo de escritura
  • Crea Cryptostream y pasa tu extensión de archivos
  • Escribir contenidos en Cryptostream (encriptar)

Deserializar archivo:

  • Crear y abrir FileStream en modo lectura
  • Crea Cryptostream y pasa tu extensión de archivos
  • Leer de Cryptostream (descifrar)

Puede encontrar ejemplos y más información aquí:

CryptoStream

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

Ejemplo:

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


Solución simple:
Para mitigar la capacidad del usuario hackish de cambiar el puntaje, puedes escribirlo como un binario, supongo.
Otra solución:
Escribir los datos en una base de datos SQLite?