elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Ejemplos de memoria dinamica en cifrado de Beaufort
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Ejemplos de memoria dinamica en cifrado de Beaufort  (Leído 2,612 veces)
do-while


Desconectado Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Ejemplos de memoria dinamica en cifrado de Beaufort
« en: 21 Octubre 2011, 04:10 am »

¡Buenas!

He visto que ultimamente hay bastantes preguntas sobre memoria dinamica. Aqui os dejo un pequeño programa que la utiliza varias veces y con distintos tipos de puntero. Espero que podais usarlo como ejemplo para resover vuestros propios problemas.

Para los interesados en criptografia, tengo que decir que es una variante del cifrado de Beaufort en el que se pueden utilizar varias claves para añadir seguridad al cifrado:

Código
  1. /*
  2.  
  3.     Utilidad que cifra ficheros basandose en el cifrado de Beaufort con claves multiples
  4.  
  5.     Al ultilzar claves multiples, la longitud de la clave resultante sera el minimo comun
  6. multiplo de todas las claves utilizadas.
  7.  
  8.     cifra +|- "claves" fichero_de_entrada fichero_de_salida
  9.  
  10.     +: cifrar
  11.     -: descifrar
  12.  
  13. */
  14.  
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #include <string.h>
  18.  
  19. /* funcion que guarda en tokens las palabras contenidas en s y devuelve el numero de parabras extraidas */
  20. int tokenize(char *s, char ***tokens);
  21.  
  22. /* carga en (*s) el contenido del fichero al que apunta f */
  23. unsigned long cargar_fichero(FILE *f, unsigned char** s);
  24.  
  25. /*
  26.  
  27. calcula el coeficiente nsimo segun el siguiene criterio:
  28.  
  29. ultima_clave[posicion % longitud ultima_clave] -
  30. penultima_clave[posicion % longitud penuultima_clave] +
  31. antepenultima_clave[posicion % longitud antepenultima_clave] +
  32. ... + o - (segun el numero de claves) primera_clave[posicion % longitud primera_clave]
  33. */
  34. int coeficiente(unsigned long posicion, char **claves, int nclaves);
  35.  
  36. /*
  37.     cifrado[i] = coeficiente[i] + o - (depende del numero de claves) texto_plano[i] mod 256;
  38.  
  39.     tomando la clase de quivalencia positiva entre 0 y 255
  40. */
  41. int cifrar(unsigned char *s, unsigned long longitud, char **claves, int nclaves);
  42.  
  43.  
  44. /*
  45.     texto_plando[i] = 1 o (-1) (depende del numero de claves) * (cifrado[i] - coeficiente[i]) mod 256;
  46.  
  47.     tomando la clase de quivalencia positiva entre 0 y 255
  48. */
  49. int descifrar(unsigned char *s, unsigned long longitud, char **claves, int nclaves);
  50.  
  51. /*
  52.  
  53.     las siguientes funciones calculan el minimo comun multiplo y maximo comun divisor de dos enteros
  54.  
  55. */
  56. unsigned long mcm(unsigned long a, unsigned long b);
  57. unsigned long mcd(unsigned long a, unsigned long b);
  58.  
  59. int main(int argc, char *argv[])
  60. {
  61.    FILE *f; /* fichero de entrada y de salida */
  62.    char **claves = NULL; /* variable para guardar las claves introducidas */
  63.    unsigned char *contenido = NULL; /* puntero para almacenar el contenido del fichero */
  64.    unsigned long longitud, nclaves; /* longitud del fichero y numero de claves introducidas*/
  65.  
  66.    if(argc != 5)
  67.    {
  68.        printf("\ncomando: cifra +|- \"claves\" fic_entrada fic_salida\n\n+: cifrar\n-: descifrar\n");
  69.    }
  70.    else
  71.    {
  72.        if(!(f = fopen(argv[3] , "rb")))
  73.            printf("No se puede abrir el fichero: %s\n", argv[3]);
  74.        else
  75.        {
  76.            if((longitud = cargar_fichero(f,&contenido)) == (unsigned long)(-1))
  77.            {
  78.                printf("Ha ocurrido un error al cargar el contenido del fichero de entrada.\n");
  79.                fclose(f);
  80.            }
  81.            else
  82.            {
  83.                if((nclaves = tokenize(argv[2] , &claves)) != (unsigned long)(-1))
  84.                {
  85.                    if(!strcmp(argv[1],"+"))
  86.                    {
  87.                        if(!cifrar(contenido,longitud,claves,nclaves))
  88.                            printf("\nHa ocurrido un error en el proceso de cifrado.\n");
  89.                        else
  90.                        {
  91.                            if(!(f = fopen(argv[4] , "wb")))
  92.                                printf("No se puede abrir el fichero: %s\n", argv[4]);
  93.                            else
  94.                            {
  95.                                fwrite(contenido,longitud,1,f);
  96.                                fclose(f);
  97.                            }
  98.                        }
  99.  
  100.                        free(contenido);
  101.  
  102.                        for(longitud = 0 ; longitud < nclaves ; longitud++)
  103.                            free(claves[longitud]);
  104.                        free(claves);
  105.                    }
  106.                    else if(!strcmp(argv[1],"-"))
  107.                    {
  108.                        if(!descifrar(contenido,longitud,claves,nclaves))
  109.                            printf("\nHa ocurrido un error en el proceso de descifrado.\n");
  110.                        else
  111.                        {
  112.                            if(!(f = fopen(argv[4] , "wb")))
  113.                                printf("No se puede abrir el fichero: %s\n", argv[4]);
  114.                            else
  115.                            {
  116.                                fwrite(contenido,longitud,1,f);
  117.                                fclose(f);
  118.                            }
  119.                        }
  120.  
  121.                        free(contenido);
  122.  
  123.                        for(longitud = 0 ; longitud < nclaves ; longitud++)
  124.                            free(claves[longitud]);
  125.                        free(claves);
  126.                    }
  127.                    else
  128.                        printf("\ncomando: cifra +|- \"claves\" fic_entrada fic_salida\n\n+: cifrar\n-: descifrar\n");
  129.                }
  130.                else
  131.                {
  132.                    printf("\nHa ocurrido un error al cargar las claves.\n");
  133.                    free(contenido);
  134.                }
  135.            }
  136.        }
  137.    }
  138.  
  139.    return 0;
  140. }
  141.  
  142. unsigned long cargar_fichero(FILE *f,unsigned char **ptr)
  143. {
  144.    unsigned long pos, len;
  145.  
  146.    /* calculamos la longitud del fichero */
  147.    pos = ftell(f);
  148.    fseek(f,0,SEEK_END);
  149.    len = ftell(f);
  150.    fseek(f,pos,SEEK_SET);
  151.  
  152.    /* asignamos tantos bytes como tenga el fichero */
  153.    if(((*ptr) = (unsigned char *) malloc(len * sizeof(unsigned char))) != NULL)
  154.        /* y cargamos el contenido */
  155.        fread((*ptr),len,1,f);
  156.    else
  157.        len = (unsigned long)(-1);
  158.  
  159.    return len;
  160. }
  161.  
  162. int tokenize(char *s, char ***tokens)
  163. {
  164.    char **aux; /* variable auxiliar para ir añadiendo una cadena mas a la lista */
  165.    char *palabra; /* palabra extraida de la cadena s*/
  166.    int npalabras = 0,i; /* numero de palabras y contador para bucles */
  167.  
  168.    /* intentamos leer una palabra */
  169.    palabra = strtok(s," ");
  170.  
  171.    (*tokens) = NULL;
  172.  
  173.    while(palabra)
  174.    {
  175.        /* si se ha encontrado una palabra incrementamos el recuento de palabras*/
  176.        npalabras++;
  177.  
  178.        /* hacemos que aux contenga tantos punteros a char como paralbras haya */
  179.        if(!(aux = (char **) realloc((*tokens) , npalabras * sizeof(char*))))
  180.        {
  181.            for(i = 0 ; i < npalabras - 1 ; i++)
  182.                free((*tokens)[i]);
  183.  
  184.            free(*tokens);
  185.            (*tokens) = NULL;
  186.  
  187.            return -1;
  188.        }
  189.        else
  190.        {
  191.            /* asignamos la ultima palabra leida */
  192.            aux[npalabras - 1] = (char *) malloc(sizeof(char) * (strlen(palabra) + 1));
  193.            strcpy(aux[npalabras - 1] , palabra);
  194.  
  195.            /* y hacemos que la variable de entrada/salida apunte al nuevo conjunto de palabras */
  196.            (*tokens) = aux;
  197.        }
  198.  
  199.        /* intentamos leer la siguiente palabra */
  200.        palabra = strtok(NULL , " ");
  201.    }
  202.  
  203.    return npalabras;
  204. }
  205.  
  206. int coeficiente(unsigned long posicion, char **claves, int nclaves)
  207. {
  208.    int c=0;
  209.    unsigned long j;
  210.  
  211.    for(j = 0 ; j < nclaves ; j++)
  212.    {
  213.        if((nclaves - 1 - j) % 2)
  214.            c -= claves[j][posicion % strlen(claves[j])];
  215.        else
  216.            c += claves[j][posicion % strlen(claves[j])];
  217.    }
  218.  
  219.    return c;
  220. }
  221.  
  222. int cifrar(unsigned char *s, unsigned long longitud, char **claves, int nclaves)
  223. {
  224.    unsigned long i;
  225.    char *clave;
  226.    unsigned long long_clave=1;
  227.  
  228.    /* la longitud de la clave final sera el mcm de las longitudes de las claves */
  229.    for(i = 0 ; i < nclaves ; i++)
  230.        long_clave = mcm(long_clave , strlen(claves[i]));
  231.  
  232.    if(!(clave = (char*) malloc(long_clave * sizeof(char))))
  233.        return 0;
  234.  
  235.    for(i = 0 ; i < long_clave ; i++)
  236.        clave[i] = coeficiente(i,claves,nclaves);
  237.  
  238.    for(i = 0 ; i < longitud ; i++)
  239.        s[i] = (nclaves * 256 + (clave[i % long_clave] + (1 - 2 *(nclaves % 2)) * s[i])) % 256;
  240.  
  241.    free(clave);
  242.  
  243.    return 1;
  244. }
  245.  
  246. int descifrar(unsigned char *s, unsigned long longitud, char **claves, int nclaves)
  247. {
  248.    unsigned long i;
  249.    char *clave;
  250.    unsigned long long_clave=1;
  251.  
  252.    for(i = 0 ; i < nclaves ; i++)
  253.        long_clave = mcm(long_clave , strlen(claves[i]));
  254.  
  255.    if(!(clave = (char*) malloc(long_clave * sizeof(char))))
  256.        return 0;
  257.  
  258.    for(i = 0 ; i < long_clave ; i++)
  259.        clave[i] = coeficiente(i,claves,nclaves);
  260.  
  261.    for(i = 0 ; i < longitud ; i++)
  262.        s[i] = (nclaves * 256 + ((1 - 2 * (nclaves % 2)) * (s[i] - clave[i % long_clave]))) % 256;
  263.  
  264.    free(clave);
  265.  
  266.    return 1;
  267. }
  268.  
  269. unsigned long mcm(unsigned long a, unsigned long b)
  270. {
  271.    return (a * b) / mcd(a,b);
  272. }
  273.  
  274. unsigned long mcd(unsigned long a, unsigned long b)
  275. {
  276.    if(a < b)
  277.    {
  278.        a ^= b;
  279.        b ^= a;
  280.        a ^= b;
  281.    }
  282.  
  283.    if(!b)
  284.        return a;
  285.  
  286.    return mcd(b , a % b);
  287. }
  288.  

Se debe utilizar desde la linea de comandos, por lo que es recomendable dejar el ejecutable en c:\windows\system32 para sistemas windows, \bin en sistemas UNIX y en general, en el directorio en el que se encuentren por defecto los comandos del sistema.

Para cifrar un fichero llamado "prueba" con la clave "clave de prueba" y como fichero de salida "cifrado", se debera hacer:
Código:
cifra + "clave de prueba" prueba cifrado
suponiendo que nombre del ejecutable sea cifra.

Para obtener el texto plano se utilizara la misma sintaxis utilizando el parametro - en lugar de +.

¡Saludos y espero que os sirva de referencia!

PD: Si veis algun error avisad, que uno es humano y por lo tanto propenso a cometer errores. Lo mismo si teneis alguna sugerencia.

¡Saludos!


En línea

- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Ayuda memoria de comandos Gnu-Linux con útiles ejemplos
Scripting
scalverth 0 3,828 Último mensaje 22 Septiembre 2012, 03:30 am
por scalverth
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines