Cifrar variables o textos de forma sencilla.

Iniciado por Meta, 29 Marzo 2018, 08:47 AM

0 Miembros y 1 Visitante están viendo este tema.

Meta

Buenas gente:

Hice un ejemplo con este código.
Código (csharp) [Seleccionar]
using System;

namespace Encriptar_variable_Consola_01
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "Ocultar variable"; // Título de la pantalla.

            string variable = "Esto es una prueba.";

            Console.WriteLine(variable);
            Console.WriteLine("Otra prueba.");

            Console.ReadKey(); // Pulse cualquier tecla para salir.
        }
    }
}


Mirando el ejecutable en el editor hexadecimal. Si encuentra los valores de las variables como indica la captura.


Uso Visual Studio 2017 Community. No quiero usar técnica de obfuscación, no se si esta versión la incluye. Quiero saber si existe la manera de camuflar esas variables.

Mi idea era usar algo parecido a esto en XOR ^10 con otro programa que haré a parte.

Código (csharp) [Seleccionar]
    for (int i = 0; i < variable.Length; i++)
    {
        variable[i] = (byte)(variable[i] ^ 10);
    }


El código de ejemplo de una variable tipo array desordenarlo.

Luego copio y pego el resultado ya codificado en la variable que es el que estoy usando ahora. En este caso uso una variable tipo string.

Tengo que hacer de alguna manera, al ejecutar el programa, lea las variables codificadas y las vuelva a poner bien para que se lea en cristiano, luego lo guarda en otra variable y Console.WriteLine lo muestra.

Espero que se entienda lo que quiero decir o lo explico de otra manera.

¿Alguna ocurrencia?

Saludos.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Eleкtro

#1
Puedes usar la clase SecureString para asignar un string mediante el cifrado en un bloque de memoria no administrada, pero no se si esa solución se ajustará a las necesidades que tengas:

+

no se muy bien lo que quieres conseguir, y tampoco soy un experto en cifrado ni obfuscación avanzada, pero no veo que quieres conseguir mediante XOR para ocultar un string en el código IL...

Yo creo que el compañero @KuBoX debe tener buena idea sobre estos temas, a ver si se deja ver por aquí...

Saludos








Meta

Hola:

Es exactamente lo que explicó nuestro amigo forero aquí, pero en vez de un array, un string que no se como se hace.

https://foro.elhacker.net/net/modificar_el_array_de_byte-t462782.0.html;msg2102256#msg2102256

Saludos.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/


Meta

Gracias.

No quería tanto código, con una mini protección ya me vale.

Si tengo un array, hago este código y me basta.

Código (csharp) [Seleccionar]
    for (int i = 0; i < var1.Length; i++)
    {
        var1[i] = (byte)(var1[i] ^ 10);
    }


Solo tengo este string que dice:

Código (csharp) [Seleccionar]
string var1 = "Esto es una prueba.";
Console.WriteLine = var1;


Cuando usas el for arriba otra vez que es un XOR ^10, con usar el mismo, vuelve los valores como estaba.

Ahora la variable var1 en su interior lo transforma en "mjcgpow5yp4g0,xy43ph". Si vuelvo aplicar el for pero con la variable var1 igual a mjcgpow5yp4g0,xy43ph, al final dice "Esto es una prueba.".

El for de arriba mira un array, pero en este caso es un string, en el cual no se que hacer para que funcione en un string. Ahí está mi problema.

Saludos.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Serapis

En efecto es suficiente con XOR, para algo simple... pero no en la forma que haces.

Es preferible que uses una clave, que luego expandas hasta cierto tamaño... ese valor es el que usas para cifrar con XOR.

Tu problema con la cadena se resume en un problema de falta de conocimientos del lenguaje.
NET, dispone múltiples funciones de tratamiento de cadenas, alguna de ellas convierte una cadena en un array de bytes (busca GetBytes (creo recordar que en Codificacion)), algo más pobre sería tomar carácter a caracter y convertirlo a byte, pero sabiendo que son cadenas muy cortas (no tochos de 1Gb. por ejemplo) incluso es perfectamente válido... hasta 1Mb... o algo más será prácticamente inmediato...


Un ejemplo en pseudocódigoVB...

array de bytes = Funcion Code(String ElTexto, String LaClave)
    Array de bytes Cifrado() = text.encoding.Getbytes(Eltexto)
    Array de bytes Key() = encoding.GetBytes(Ampliar(LaClave, Cifrado.lenght))

    Bucle para k desde 0 hasta txt.lenght
        Cifrado(k) = Cifrado(k) xor key(k)
    Fin bucle

    Devolver Cifrado
Fin funcion

String = Funcion Decode(Array de bytes Cifrado, String LaClave)
    Array de bytes Key() = Ampliar(LaClave, Cifrado.lenght))

    Bucle para k desde 0 hasta txt.lenght
        Txt(k) = txt(k) xor key(k)
    Fin bucle

    Devolver text.Encoding.GetString(Eltexto)
Fin funcion

' Dado un texto, lo amplía hasta como mínimo el tamaño pedido.
'   en cada ciclo, se duplica el tamaño previo.
Array de bytes = Funcion Ampliar(string Key, entero Minimo)
    entero i, j, k
    array de bytes tmp()
    Array de bytes yeK() = encoding.GetBytes(Key)

    k= yek.Lenght: j=k
    Hacer mientras (k < minimo)
        k = ((k*2)-1)
        redimensionar tmp(0 a k)
        ' El byte primero es la media de los extremos, luego entre el 2ª y el penúltimo, luego entre el 3º y el antepenúltimo...
        ' el byte último es un xor entre los extremos, luego entre el 2ª y el penúltimo, luego entre el 3º y el antepenúltimo...
        ' es muy simple, pero puede complicarse todo lo que quieras... y para lo que necesitas es suficiente.
        bucle para i desde 0 hasta j
            tmp(i) = (yek(i) + yek(j-i) \2)
            tmp(k-i) = (yek(i) xor yek(j-i))
        fin bucle
        ' Se puede complicar más con otras fases: 2,3,4 alterando la forma o la forma en que los índices se conjugan.

         yeK = tmp ' asignamos un array al otro...
        j = k
    Repetir

    Devolver yeK
Fin funcion
' NOTA: Revisa... que es probable que tengas que corregir el tamaño del array temporal (k = ((k*2)-1) ), lo he hecho al vuelo, mientras escribo...



...por qué no?... usaremos de ejemplo, una de las 'contraseñas' más usadas en el planeta....

Array de Bytes cif() = Code(text1.text, "QWERTYUIOP")
Text2.Text = Decode(cif, "QWERTYUIOP")


Ni qué decir que la clave debe ser la misma en mabos casos...

Si no te vale tener de vuelta un array de bytes, porque por ejemplo tienes que mostrarlo en una caja de texto, y muchos bytes no son imprimibles, pués lo pasas por una función a Base64 y listo...


Text3.text = Convert.ToBase64String( Code(Text1.Text, "QWERTYUIOP"))
Text2.Text = Decode(convert.FromBase64String(text3.text), "QWERTYUIOP")

Meta

Buenas campeón:

Deja ver si capto lo que cuentas. Con el XOR ^10 me vale y solo quiero eso. Me da que usas la idea del Windows form y mi idea es en modo consola.

Saludos.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Serapis

#7
Cita de: Meta en 30 Marzo 2018, 12:01 PM
Deja ver si capto lo que cuentas. Con el XOR ^10 me vale y solo quiero eso.

...Me da que usas la idea del Windows form y mi idea es en modo consola.
mmmm... a ver yo leí esto:
Citar
Mi idea era usar algo parecido a esto en XOR ^10 con otro programa que haré aparte.

Es decir, yo entiendo/interpreto que usas ese programa/librería aparte (B)...
1 - Primero para cifrar lo deseado y guardarlo en el ejecutable (A)...
2 - Luego cuando se carga esté 'A', invocar a 'B' para decodificarlo.
Yo veo que cumple perfectamente lo que quieres... (aunque tienes que adaptarlo, es solo un simple ejemplo)

De todos modos, yo ni siquiera usaría un programa/librería aparte, simplemente crearía un par de métodos de extensión, para la clase String (Code, Decode haciendo justo lo que señalo más abajo más arriba) y listo... y si me apuras, ni cifrando con XOR, dejándolo simplemente en Base64, te bastaría...

Serapis

#8
...y bueno, aprovechando que es sábado y Semana Santa y que por ello tengo un poco de tiempo libre...

No acostumbro a poner código, creo que todo el que reclama algo tiene que entender lo que sele dice y poner de su parte, pero bueno... Tampoco es plan que pongan en duda, lo que uno dice, porque (al menos yo) lo que uno dice debe decirlo con conocimiento, si no es mejor callarse, ó ante la duda preguntar...

El código parte de las líneas que tienes tú, yo simplemente he añadido la extensión de los métodos para los que te señalaba más arriba, corrigiendo en efecto, los pequeños detalles que se escapan cuando escribes al vuelo la idea... esto es, funciona perfectamente.
Código (C#) [Seleccionar]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace Encriptar_variable_Consola_01{
   using CustomExtensions;
   class Program{
       static void Main(string[] args){
           string Key = "QWERTYUIOP";
           string s = "En un lugar de 'La Mancha', de cuyo nombre no quiero acordarme.";
           string r, t;
                   
           r = s.Code(Key);
           System.Console.WriteLine("El texto original {0} cifrado con la clave {1}, da por resultado {2}", s, Key, r);
           Console.WriteLine();
           t = r.Decode(Key);
           System.Console.WriteLine("...y vuelta atrás, el texto cifrado {0} con la clave {1}, nos devuelve al origen {2}", r, Key, t);
           
           Console.WriteLine();
           Console.ForegroundColor = ConsoleColor.Yellow;
           System.Console.WriteLine("Se comprueba que 's' = 't' {0} = {1}", s, t);
           Console.ForegroundColor = ConsoleColor.White;





           Console.WriteLine();  
           //Console.Title = "Ocultar variable"; // Título de la pantalla.
           Console.Title = "Ocultar variable".Code(Key) ;  
           //string variable = "Esto es una prueba.";
           string variable = "Esto es una prueba.".Code(Key) ;
           Console.WriteLine(variable);
           //Console.WriteLine("Otra prueba.");
           Console.WriteLine("Otra prueba.".Code(Key) );

           Console.WriteLine();
           Console.ForegroundColor = ConsoleColor.Red;
           Console.WriteLine("Pulse una tecla y observa como cambia el título de la consola a su estado decodificado...");
           Console.ReadKey();
           Console.Title = Console.Title.Decode(Key);

           Console.WriteLine("Pulse cualquier tecla para salir.");
           Console.ReadKey();
       }
   }
}


namespace CustomExtensions{
   //Los métodos extendidos, deben ser definidos como una clase estática.
   public static class StringExtension    {        
       public static string Code(this String ElTexto, String LaClave){
           byte[] Cifrado = Encoding.UTF8.GetBytes(ElTexto);
           byte[] Key = Encoding.UTF8.GetBytes(Ampliar(LaClave, Cifrado.Length));
           byte k;

           for (k=0; k< Cifrado.Length; k++){
               Cifrado[k] = (byte)(Cifrado[k] ^ Key[k]);
           }

           return Convert.ToBase64String(Cifrado);
       }

       public static string Decode(this string Cifrado, String LaClave){
           byte[] Cif = Convert.FromBase64String(Cifrado);            
           byte[] Key = Encoding.UTF8.GetBytes(Ampliar(LaClave, Cif.Length));
           byte k;

           for (k = 0; k < Cif.Length; k++){
               Cif[k] = (byte)(Cif[k] ^ Key[k]);
           }
           return Encoding.UTF8.GetString(Cif);
       }

       private static string Ampliar(string Key, int Minimo){
           int k, j, i;
           
           byte[] yeK = Encoding.UTF8.GetBytes(Key);
           k = yeK.Length;
           j = (k-1);
           byte[] tmp= new byte[k];
   
           while (k < Minimo){
               k = (k * 2);
               Array.Resize(ref tmp, k); //redimensionar tmp(0 a k)
               //' El byte primero es la media de los extremos, luego entre el 2ª y el penúltimo, luego entre el 3º y el antepenúltimo...
               //' el byte último es un xor entre los extremos, luego entre el 2ª y el penúltimo, luego entre el 3º y el antepenúltimo...
               //' es muy simple, pero puede complicarse todo lo que quieras... y para lo que necesitas es suficiente.
               for (i = 0; i < j; i++) {
                   tmp[i] = (byte) ((yeK[i] + yeK[j-i] ) >> 1) ;
                   tmp[k-1-i] = (byte) (yeK[i] ^ yeK[j-i]);
               }
               //' Se puede complicar más con otras fases: 2,3,4 alterando la forma o la forma en que los índices se conjugan.

               yeK = tmp; //' asignamos un array al otro...
               j = (k - 1);
           }
           return Encoding.UTF8.GetString(yeK);
       }
   }
}


NOTAS:
A --- Yo tengo el VS-2010, puede que para una versión más actual, pueda requerir algún cambio, el propio entorno, ya te sugerirá si algo es obsoleto o incluso si no lo reconoce.... por ejemplo los métodos Getbytes, GetString, podrían estar desplazados respecto de UTF8.
B --- Nunca ha manejado una versión 'Comunity', solo versiones Enterprise y Profesional, por lo que ignoro las limitaciones de las versiones Comunity, supongo que para algo tan sencillo, no deba afectarle.
C --- Fíjate en el detalle de importar el namespace, concretamente en la línea: using CustomExtensions;
D --- Al final me he mantenido firme (al pseudocódigo que puse) y he dejado el cifrado con XOR, aparte de codificar con Base64.
E --- Para probarlo y entenderlo bien, ejecútalo paso a paso (tecla F11).
F --- He añadido bastante 'verbosidad', en main, para reflejar el uso de los métodos Code y Decode.
G --- p.d.: Personalmente acostumbro a abrir las llaves en la línea previa, por lo que no estando acostumbrado pueda dar la impresión de que 'falta algo'... cuestión de gustos, solamente...
H --- ...y por supuesto y para aclarar tus dudas: Es una aplicaicón de consola, la frase tuya:  Me da que usas la idea del Windows form y mi idea es en modo consola.[/i] es irrelevante, aunque yo pusiera en el ejemplo referencias a unos controles textbox, el pseudocódigo es adaptable a ambas situaciones...
I --- Para algo más elegante, incluso la clave (QWERTYUIOP), podría estar cifrada (y ser descifrada, por ejemplo con el nombre del programa, con lo que si alguien lo cambia, 'traducirá' a urliburli), o bien ser pasada como un argumento al programa.

Meta

#9
Buenas:

Lo he probado. Funciona de maravilla.  ;-)

Tarda mucho en darle F11 todo el rato, pero se entiende. ;)

Lo que quería hacer era más sencillo, menos protección pero sencillo.

Programa A, el original, programa B el que hace el XOR ^10. Los dos hacen XOR ^10.

El tipo de varibale como ejemplo es el Byte[].
Código (csharp) [Seleccionar]
   byte[] rawData = {
       0xF5, 0xD2, 0xF5, 0xEA, 0x0A, 0x1A, 0x40, 0x4C, 0x43, 0x4C, 0x0A, 0x0B,
       0x0B, 0x0B, 0x0A, 0x42, 0x0A, 0x42, 0x0A, 0x0A, 0xF5, 0xD1, 0x0A, 0x49}


Usamos el XOR ^10.
Código (csharp) [Seleccionar]
for (int i = 0; i < rawData.Length; i++)
   {
       rawData[i] = (byte)(rawData[i] ^ 10);
   }


El problema que tengo ahora, es que no uso Byte[], sino string. Por eso estoy para arriba y para abajo.

En vez de usar como ejemplo de arriba que puse Byte[], pongo un string en cristiano. No en códigos hexadecimales.

¿Hay alguna solución sobre lo que busco?

Salu2. ;)
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/