[Aportes indexados] Encriptación con tabla pseudo-aleatoria

Dunkan

Veterano
Qué mierda hace esto tío Dunkan? Bien es sencillo.... genera una tabla "aleatoria" (en cada ejecución es diferente) con una seed random por ejemplo:

table[] = { 10, 25, 36, 11, 16, 41, 33 .... }

Después de esto agarra una string que en C son únicamente char name[subindice][dim] y hace el primer subindice del string XOR el primer subíndice de la tabla... en el código donde encripta está ejemplificado esto.

Es únicamente para aportar la idea pero con esto se puede jugar bastante y para los servidores de Argentum por ejemplo le dificultas bastante el camino a lobotein a la hora de hacerte un bot matemático que interactúa con el resto de usuarios.

C:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#define MAX_TABLE 1024

void onSend(int8_t String[][50])
{
    printf("message: ");
    fflush(stdin);
    gets(&String[0]);
}

int16_t lengthString(int8_t String[][50])
{
    int16_t length = 0;
    while (String[0][length] != '\0') length++; // Recorre el mensaje hasta encontrar '\0';
    return length;
}

void generate_table(int32_t seed, uint8_t table[])
{
    int16_t i;

    srand(seed);
    for (i = 0; i < MAX_TABLE; ++i)
    {
        table[i] = 1 + rand() % 99;
    }

}

int rdtsc() // Se lee un contador de 64 bits que cuenta hacia arriba en cada ciclo de reloj del procesador
{
    uint32_t EAX, EDX;
    __asm__ __volatile__ ("rdtsc" : "=a"(EAX), "=d"(EDX));
    return ( (uint64_t)EAX ) | ( ((uint64_t)EDX) << 32 );
}

int16_t generate_initial_seed()
{
    srand(rdtsc());
    return 1 + rand() % 100;
}

void encrypt(uint8_t table[], int8_t String[][MAX_TABLE], int16_t * initial_byte) {

    /****************************************************

    int8_t -> char -> 8 bits -> 1 byte

    Para encriptar {
        input:  'A' = 65 = 10000001     <----------|
                                XOR                |
        key:    'T' = 84 = 10101000                |
                          ----------               |
        crypted message: = 00101001 = 41           |
    }                                              |
                                                   |
    Para desencriptar {                            |
        crypted message: = 00101001 = 41           |
                                XOR                |
        key:    'T' = 84 = 10101000                |
                          ----------               |
        original message = 10000001 = 65    <------|
    }

    *****************************************************/

    int16_t i;
    for(i = 0; i < lengthString(String[0]); ++i)
    {
        String[0][i] ^= table[i + *initial_byte]; //String[0] char[i] xor table[i]
    }

    *initial_byte += i;
}

void printMessage(int8_t String[][50]) {
    int16_t i;
    for(i = 0; i < lengthString(String[0]); ++i)
    {
        printf("%c", String[0][i]);
    }
}

int main()
{
    uint8_t byte_table[MAX_TABLE];
    uint8_t charStr[10][50];

    int16_t counter_decrypt = 0;
    int16_t counter_encrypt = 0;

    generate_table(/*Seed*/ generate_initial_seed(), byte_table);

    onSend(charStr); // get message

    printf("\n[ORIGINAL]\t\t");
    printMessage(charStr);

    encrypt(byte_table, charStr, &counter_encrypt); // encriptamos haciendo un xor entre los caracteres de nuestro string y los bytes de la tabla
    printf("\n[CRYPTED]\t\t");
    printMessage(charStr);

    encrypt(byte_table, charStr, &counter_decrypt); // volvemos a hacer xor con los mimos subindices de la tabla de bytes
    printf("\n[RETURN ORIGINAL]\t");
    printMessage(charStr);

    encrypt(byte_table, charStr, &counter_encrypt); // Si volvemos a encriptar... el mensaje cambia porque continua desde el indice anterior
    printf("\n[CRYPTED]\t\t");
    printMessage(charStr);

    encrypt(byte_table, charStr, &counter_decrypt); // Pero magicamente al desencriptarlo vuelve a tener el mensaje original
    printf("\n[RETURN ORIGINAL]\t");
    printMessage(charStr);

    printf("\n");

    return 0;
}
( int8_t String[][50] ) donde 50 determina la cantidad de caracteres máximas del string... es HORRIBLE hacerlo de esta manera, pero ahi los dejo con tarea.

output:


Cualquier idea, mejora, optimización que se quiera aportar, bienvenido sea!!!! Por un mundo sin loboteins que nos hagan man in the middle!!!

Saludos!!
 
Última edición:

Dr. Wolftein

Computer's Scientist
Miembro del equipo
Administrador
Especialista de Tecnología
Qué mierda hace esto tío Dunkan? Bien es sencillo.... genera una tabla "aleatoria" (en cada ejecución es diferente) con una seed random por ejemplo:

table[] = { 10, 25, 36, 11, 16, 41, 33 .... }

Después de esto agarra una string que en C son únicamente char name[subindice][dim] y hace el primer subindice del string XOR el primer subíndice de la tabla... en el código donde encripta está ejemplificado esto.

Es únicamente para aportar la idea pero con esto se puede jugar bastante y para los servidores de Argentum por ejemplo le dificultas bastante el camino a lobotein a la hora de hacerte un bot matemático que interactúa con el resto de usuarios.

C:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#define MAX_TABLE 1024

void onSend(int8_t String[][50])
{
    printf("message: ");
    fflush(stdin);
    gets(&String[0]);
}

int16_t lengthString(int8_t String[][50])
{
    int16_t length = 0;
    while (String[0][length] != '\0') length++; // Recorre el mensaje hasta encontrar '\0';
    return length;
}

void generate_table(int32_t seed, uint8_t table[])
{
    int16_t i;

    srand(seed);
    for (i = 0; i < MAX_TABLE; ++i)
    {
        table[i] = 1 + rand() % 99;
    }

}

int rdtsc() // Se lee un contador de 64 bits que cuenta hacia arriba en cada ciclo de reloj del procesador
{
    uint32_t EAX, EDX;
    __asm__ __volatile__ ("rdtsc" : "=a"(EAX), "=d"(EDX));
    return ( (uint64_t)EAX ) | ( ((uint64_t)EDX) << 32 );
}

int16_t generate_initial_seed()
{
    srand(rdtsc());
    return 1 + rand() % 100;
}

void encrypt(uint8_t table[], int8_t String[][MAX_TABLE], int16_t * initial_byte) {

    /****************************************************

    int8_t -> char -> 8 bits -> 1 byte

    Para encriptar {
        input:  'A' = 65 = 10000001     <----------|
                                XOR                |
        key:    'T' = 84 = 10101000                |
                          ----------               |
        crypted message: = 00101001 = 41           |
    }                                              |
                                                   |
    Para desencriptar {                            |
        crypted message: = 00101001 = 41           |
                                XOR                |
        key:    'T' = 84 = 10101000                |
                          ----------               |
        original message = 10000001 = 65    <------|
    }

    *****************************************************/

    int16_t i;
    for(i = 0; i < lengthString(String[0]); ++i)
    {
        String[0][i] ^= table[i + *initial_byte]; //String[0] char[i] xor table[i]
    }

    *initial_byte += i;
}

void printMessage(int8_t String[][50]) {
    int16_t i;
    for(i = 0; i < lengthString(String[0]); ++i)
    {
        printf("%c", String[0][i]);
    }
}

int main()
{
    uint8_t byte_table[MAX_TABLE];
    uint8_t charStr[10][50];

    int16_t counter_decrypt = 0;
    int16_t counter_encrypt = 0;

    generate_table(/*Seed*/ generate_initial_seed(), byte_table);

    onSend(charStr); // get message

    printf("\n[ORIGINAL]\t\t");
    printMessage(charStr);

    encrypt(byte_table, charStr, &counter_encrypt); // encriptamos haciendo un xor entre los caracteres de nuestro string y los bytes de la tabla
    printf("\n[CRYPTED]\t\t");
    printMessage(charStr);

    encrypt(byte_table, charStr, &counter_decrypt); // volvemos a hacer xor con los mimos subindices de la tabla de bytes
    printf("\n[RETURN ORIGINAL]\t");
    printMessage(charStr);

    encrypt(byte_table, charStr, &counter_encrypt); // Si volvemos a encriptar... el mensaje cambia porque continua desde el indice anterior
    printf("\n[CRYPTED]\t\t");
    printMessage(charStr);

    encrypt(byte_table, charStr, &counter_decrypt); // Pero magicamente al desencriptarlo vuelve a tener el mensaje original
    printf("\n[RETURN ORIGINAL]\t");
    printMessage(charStr);

    printf("\n");

    return 0;
}
( int8_t String[][50] ) donde 50 determina la cantidad de caracteres máximas del string... es HORRIBLE hacerlo de esta manera, pero ahi los dejo con tarea.

output:


Cualquier idea, mejora, optimización que se quiera aportar, bienvenido sea!!!! Por un mundo sin loboteins que nos hagan man in the middle!!!

Saludos!!
Encriptaciones asimetricas siempre van a sufrir del MITM (Y una encriptacion que solo usar xor cuesta menos de 1 minuto encontrar todas las posibles llaves que utilizes. Con solo saber como es el header del paquete, cada paquete que interceptas hace un bruteforce de la llave que utilizes en xor hasta reconstruir toda la tabla.

Ademas para que el servidor y el cliente se comuniquen en el mismo idioma, el cliente o servidor debe mandar esa tabla generada lo cual puede ser interceptada facilmente y todo tu sistema queda inutilizado.
 
Última edición:

Dunkan

Veterano
Encriptaciones simetricas siempre van a sufrir del MITM (Y una encriptacion que solo usar xor cuesta menos de 1 minuto encontrar todas las posibles llaves que utilizes. Con solo saber como es el header del paquete, cada paquete que interceptas hace un bruteforce de la llave que utilizes en xor hasta reconstruir toda la tabla.

Ademas para que el servidor y el cliente se comuniquen en el mismo idioma, el cliente o servidor debe mandar esa tabla generada lo cual puede ser interceptada facilmente y todo tu sistema queda inutilizado.
En realidad no... debería enviar únicamente la seed y la tabla la genera tanto el cliente como el servidor por separado, esa es la idea general. La primer idea que dejaste es excelente jajajajaja, no se me hubiese ocurrido
 

Dr. Wolftein

Computer's Scientist
Miembro del equipo
Administrador
Especialista de Tecnología
En realidad no... debería enviar únicamente la seed y la tabla la genera tanto el cliente como el servidor por separado, esa es la idea general. La primer idea que dejaste es excelente jajajajaja, no se me hubiese ocurrido
Bien intercepto la seed, miro el codigo del cliente hasta encontrar la funcion que tomando la seed genera la tabla y listo; anti anti lobotein.
 

Facuweekend

Destructor Lvl 1
@Wolftein @Dunkan yo creo que si me miro toda una serie japonesa sin subtitulos al español entiendo mas eso de lo que están hablando :p

pd:gracias por el aporte aunque yo no entienda nada jajaj
 

Zirelay.

Newbie Lvl 4
Es cierto que la encriptación es super vulnerable. Pero es bastante decente para lo que es el ámbito de argentum. (al menos que tengas un servidor de la c* de su madre y puedas permitirte un algoritmo más complejo).

Lo que se puede hacer para mejorar esto es implementar un buen handshake donde se ejecuten mil instrucciones de código basura, e intercambiar varios paquetes para enviar la seed fragmentada junto con también información basura.

De todas formas, haciendo eso, lo único que ganas es marear a quien te vaya a querer romper la encriptación.
Ojo, si es alguien recién iniciado, es muy probable que lo frustres y safaste.

Pero, lamentablemente, a la larga toda seguridad es vulnerable. Sólo hace falta un poco de motivación por parte del hacker :p

Gracias por el aporte, desp lo pruebo!

salute
 
Última edición:

Dunkan

Veterano
Es cierto que la encriptación es super vulnerable. Pero es bastante decente para lo que es el ámbito de argentum. (al menos que tengas un servidor de la c* de su madre y puedas permitirte un algoritmo más complejo).

Lo que se puede hacer para mejorar esto es implementar un buen handshake donde se ejecuten mil instrucciones de código basura, e intercambiar varios paquetes para enviar la seed fragmentada junto con también información basura.

De todas formas, haciendo eso, lo único que ganas es marear a quien te vaya a querer romper la encriptación.
Ojo, si es alguien recién iniciado, es muy probable que lo frustres y safaste.

Pero, lamentablemente, a la larga toda seguridad es vulnerable. Sólo hace falta un poco de motivación por parte del hacker :p

Gracias por el aporte, desp lo pruebo!

salute
Hemos pasado blowfish, RC4... nada es impenetrable.

edit: salvo mi mujer
 
Arriba