domingo, 24 de septiembre de 2017

Cifrado RC4

RC4 es un esquema de cifrado de flujo (no basado en bloques) simétrico.

Es un esquema de cifrado extremadamente simple y puede implementarse en software de forma muy eficiente. Esto lo ha convertido en uno de los esquemas de cifrado más utilizados del mundo. RC4 fue excluido enseguida de los estándares de alta seguridad por los criptógrafos y algunos modos de usar el algoritmo de criptografía RC4 lo han llevado a ser un sistema de criptografía muy inseguro, incluyendo su uso WEP. No está recomendado su uso en los nuevos sistemas, sin embargo, algunos sistemas basados en RC4 son lo suficientemente seguros para un uso común.


Descripción


RC4 es un algoritmo simple, este consiste en 2 algoritmos:

1-Algoritmo de programacion de claves (KSA)
2-Algoritmo de generacion Pseudo-Aleatoria (PRGA).

Cada uno de estos algoritmos usa un array de 256 números en el que ambos son únicos en cuanto a rango y su valor va desde 0 hasta 255. Todos los números de 0 a 255 existen dentro del array, pero están solo mezclados de diferentes maneras, el KSA se encarga de realizar la primera mezcla en el S-Box, basado en el valor de la semilla dada dentro de él, y esta "semilla" puede ser de 256 bytes de largo.


Algoritmo


Primero, el S-box array, es decir nuestro arreglo S[] es llenado con valores secuenciales desde 0-255, entonces, el otro array de 256-bytes es llenado con el valor de la "semilla", repitiendo como sea necesario hasta que todo el array es llenado. Este array será llamado K, entonces el array S es mezclado usando el siguiente pseudocódigo:




Una vez que eso es hecho, la S-box es intercambiada basándose en el valor de la "semilla". Esa es la "Key" programada para el algoritmo, algo sencillo.

Ahora que hemos generado la "Key" se usa el Algoritmo de generacion Pseudo-Aleatoria (PRGA). Este algoritmo tiene 2 contadores, el i y la j, en el cual ambos son inicializados en 0 para comenzar. Después de eso, cada byte de la "Key" generada es usada en el siguiente Pseudo-Code:





El valor expuesto del byte de S[t] es el primer byte del keystream, repitiéndose el algoritmo descrito para conseguir bytes adicionales de keystream.

RC4 es lo suficientemente sencillo como para ser almacenado e implementado al facilmente, aunque la robustez de dicho algoritmo depende, en gran medida, de la implementación y utilización realizada, existiendo graves problemas conocidos en la implementación del sistema de cifrado WEP, diseñado para ofrecer confidencialidad en redes Wireless.

Implementación


Bueno he tomado el ejemplo y lo he modificado para pasarlo por parámetros el texto a cifrar y la clave y he comentado algunas partes para comprenderlo mejor, el código lo pueden visualizar mejor desde aqui.

En resumen la función void rc4_generar_vector(unsigned char *key, unsigned int key_length) recibe como parámetro la clave la cual ingresamos y el tamaño de nuestra clave. Luego inicializa nuestro Array S[] asignándoles valores secuenciales desde el 0-255 y luego genera el Array S[] pero con los valores intercambiados por el algoritmo mostrado en la primera imagen que utiliza la clave ingresada al inicio.

Por otro lado la función unsigned char rc4_salida()  genera el cifrado del texto ingresado inicialmente aplicando un XOR entre el caracter x del texto (texto[x]) y un valor "pseudo-aleatorio" del Array S[] generado anteriormente.

Bueno en la siguiente imagen podemos visualizar el programa funcionando:

*Nota: Podemos observar como al varial el texto a cifrar agregandole una letra mas, el resultado varia solo al final.


El codigo:

/**
    Autor: PaoloRamirez
    Tema: Cifrado RC4
    Link: https://www.facebook.com/PaoloProgrammer/
**/

#include <stdio.h>
#include <string.h>
#include <stdlib.h> 

unsigned char S[256];
unsigned int i, j;

/**
    Intercambiar valores entre i y j
**/
void intercambiar(unsigned char *s, unsigned int i, unsigned int j) 
{
    unsigned char temp = s[i];
    s[i] = s[j];
    s[j] = temp;
}

/**
    KSA - Algoritmo de programacion de claves
**/
void rc4_generar_vector(unsigned char *key, unsigned int key_length) 
{

    //Asignar valores iniciales al Array S[]
    for (i = 0; i < 256; i++)
    {   
        S[i] = i;
    }
 
    //Genera semilla con la clave ingresada, altera los valores de S[]
    for (i = j = 0; i < 256; i++) 
    {   
        j = (j + key[i % key_length] + S[i]) & 255;
        intercambiar(S, i, j);  
    }
 
    i = j = 0;
}
 
/**
    PRGA - Algoritmo de generacion Pseudo-Aleatoria
**/
unsigned char rc4_salida() 
{
    i = (i + 1) & 255;
    j = (j + S[i]) & 255;

    intercambiar(S, i, j);

    return S[(S[i] + S[j]) & 255];
}

int main(int argc, char **argv) 
{

    int len_texto,len_clave;
    len_texto=strlen(argv[1]);
    len_clave=strlen(argv[2]);

    /**
        Texto inicial
        Clave de cifrado
    **/
    //Tamaño de cadena = len+fincadena \0
    char texto[len_texto+1];
    char clave[len_clave+1];

    //Format
    memset(texto,0,sizeof(texto));
    memset(clave,0,sizeof(clave));

    //Copiar a variables
    strcpy(texto,argv[1]);
    strcpy(clave,argv[2]);
 
    
    int x;
    rc4_generar_vector(clave, strlen(clave));

    for (x = 0; x < strlen(texto); x++)
    {
        printf("%02X", texto[x] ^ rc4_salida());
    }

    printf("\n");
    
}


Enlaces:



Referencias:


1 comentario:

  1. Amigo, muy buena explicación sin embargo tu código no compila, gracias de antemano.

    ResponderBorrar