Foro de elhacker.net

Seguridad Informática => Criptografía => Mensaje iniciado por: JoseluCross en 29 Marzo 2016, 17:37 pm



Título: Sistema de cifrado por lote de texto plano
Publicado por: JoseluCross en 29 Marzo 2016, 17:37 pm
Hola a todos, un amigo y yo hemos estado trasteando un poco con C y hemos creado un cifrado algo simplón y queremos saber como de fuerte es. Os comento un poco como funciona. Se mete un texto de entrada y uan contraseña y en la salida cada caracter de la entrada se sumará al caracter correspondiente de la contraseña siguiendo este esquema, tanto para el cifrado como el descifrado.
Código:
/*
 *Title: crypt
 *Description: It de/encrypt strings
 *@param pass[]: string which we use like password
 *@param text[]: string which we will encrypt
 *@param x: false = encrypt, true = decrypt
 *@param name[]: name of output
 *@return text_length: text length
 */
void crypt(char pass[], char text[], bool x, char name[]) {
  int     pass_length;
  int     text_length;
  int     passPosition = 0; //Relative position in pass[]
  int     textPosition = 0; //Relative position in text[]
  pass_length = length(pass);
  text_length = length(text);
  int     sol; //output character

  FILE   *nom;

  nom = fopen(name, "w");

  for(textPosition = 0; textPosition < text_length; textPosition++) {
    if(passPosition == pass_length) {
      passPosition = 0;
    }
    if(x == false) {
      sol = text[textPosition] + pass[passPosition];
      while(sol > 126) {
sol -= 94;
      }
    } else {
      sol = text[textPosition] - pass[passPosition];
      while(sol < 32) {
sol += 94;
      }
    }
    passPosition++;
    fputc(sol, nom);
  }
  fclose(nom);
}
Además tiene la opción de generar texto aleatorio tras la salida para meter datos que no forman parte del texto original y creemos que permite una barrera contra un ataque por estadistica de palabras.
Todo el código está en https://github.com/JoseluCross/cryptoJKA/tree/master/cryptojka (https://github.com/JoseluCross/cryptoJKA/tree/master/cryptojka)

Queremos saber si es seguro, o al menos, cuan seguro es. Muchas gracias


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: AlbertoBSD en 29 Marzo 2016, 17:50 pm
Practico el ejemplo, para fines de aprendizaje sobre sistemas de cifrados es buen trabajo, aun que realmente seguro no es.

Lo de agregar texto random suena bien, sin embargo la seguridad atravez de la oscuridad no estan segura.

Aun asi buen ejemplo para fines practicos.


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: JoseluCross en 29 Marzo 2016, 18:04 pm
Muchas gracias por tu comentario. ¿Como sería el modo para descifrar el contenido cifrado sin la clave correcta? Me interesa mucho el tema pero estoy algo verde. Muchas gracias.


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: AlbertoBSD en 29 Marzo 2016, 18:20 pm
Como tu lo comentas un ataque por estadistica podria arrojar algo de luz sobre la distribución / frecuencia de los datos.

Código
  1. #include<stdio.h>
  2. #include<string.h>
  3.  
  4. int main() {
  5. char *pass = "HolaMundo";
  6. char *text = "QWERT456Y76U76I7OP6A756S7D567F6G7H56J7K67L6Ñ7Z56X7C567V65B7N65M7q56w2e3r2t41213yuiopasdfghjklzxcugjh877yvbty7t6645r311nm";
  7. int x = 1;
  8. char *name = "salida.txt";
  9. crypt(pass,text,x,name);
  10. return 0;
  11. }
  12.  

Hice este codigo para testear tu algoritmo, deja checo la salida y la analizo.

Cambie los length por strlen y cambie los bool por int para podrelo compilar sin errores, no se que compilador estes usando, en fin con los cambios que le hice funciona bien.

Esta fue la salida:

Citar
gF7Oe{%0HM%G4G2'I?L0)2G<'>$L&83X 8/%`&=3H5&y<MI'3i 3/%ME(2S >0$c&c2G`"_"*!f1By!-h-Xamr\T`V Y]i-aSoV"W*4Hbf\c1&f3G{%l"G `j
Saludos!


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: JoseluCross en 29 Marzo 2016, 18:38 pm
Yo uso gcc, la funcion lenght es una función que implementé en el código. El código completo es

Del data.h
Código:
//Here all constant are defined

#define MAX_TEXT 1048576
#define MAX_PASS 64
#define VERSION "0.4.2"
del main.c
Código:
/*Title: cryptojka
 *Descripton: cryptation character by character
 *Autor: José Luis Garrido Labrador (JoseluCross) and Kevin Puertas Ruiz (Kprkpr)
 *Version: 0.4.2 - mar/16
 */
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include "data.h"

#include "methods.c"

int     clean_stdin(void);
void    crypt(char[], char[], bool, char[]);
int     length(char[]);

int main(int argc, char *argv[]) {
  bool    state; //false when encrypt, true when decrypt
  bool    ran = false; //false: not random generation, true: random generation
  bool    fil; //false: not file, true, with file
  bool    cond = false; //If false = not argument
  int     cant = 0; //number of characters in random generation
  char    text[MAX_TEXT] = "text"; //imput character
  char    pass[MAX_PASS] = "pass"; //Imput pass
  FILE   *in; //Input file
  char    out[35] = "crypt.out"; //output file

  //Flags options
  int     i;
  for(i = 0; i < argc; i++) {
    if(strcmp(argv[i], "-e") == 0) {
      state = false;
      cond = true;
    } else if(strcmp(argv[i], "-d") == 0) {
      state = true;
      cond = true;
    } else if(strcmp(argv[i], "-f") == 0) {
      in = fopen(argv[i + 1], "r");
      fil = true;
      cond = true;
    } else if(strcmp(argv[i], "-o") == 0) {
      strcpy(out, argv[i + 1]);
      cond = true;
    } else if(strcmp(argv[i], "-p") == 0) {
      strcpy(pass, argv[i + 1]);
      cond = true;
    } else if(strcmp(argv[i], "-t") == 0) {
      strcpy(text, argv[i + 1]);
      fil = false;
      cond = true;
    } else if(strcmp(argv[i], "-r") == 0) {
      ran = true;
      cant = atoi(argv[i + 1]);
      cond = true;
    } else if(strcmp(argv[i], "--version") == 0
      || strcmp(argv[i], "-v") == 0) {
      printf("cryptoJKA, version: %s\n\n", VERSION);
      return 0;
    } else if(strcmp(argv[i], "-h") == 0) {
      helpbox(); //In methods.c
      return 0;
    }
  }

  if(cond == false) {
    printf("No option specified\n");
    helpbox();
    return 0;
  }

  if(state == false) {
    if(fil == false) {
      crypt(pass, text, false, out);
    } else {
      for(i = 0; feof(in) == 0; i++) {
text[i] = fgetc(in);
      }
      for(i = 0; i < length(text); i++) {
if(text[i] == '\n') {
  text[i] = ' ';
}
      }
      crypt(pass, text, false, out);
    }
    if(ran == true) {
      rangen(cant, out); //In methods.c
    }
  } else {
    if(fil == false) {
      crypt(pass, text, true, out);
    } else {
      for(i = 0; feof(in) == 0; i++) {
text[i] = fgetc(in);
      }

    }
    crypt(pass, text, true, out);
  }

  printf("\n");
  showFile(out, MAX_TEXT);

  return 0;
}

/*
 *Title: crypt
 *Description: It de/encrypt strings
 *@param pass[]: string which we use like password
 *@param text[]: string which we will encrypt
 *@param x: false = encrypt, true = decrypt
 *@param name[]: name of output
 *@return text_length: text length
 */
void crypt(char pass[], char text[], bool x, char name[]) {
  int     pass_length;
  int     text_length;
  int     passPosition = 0; //Relative position in pass[]
  int     textPosition = 0; //Relative position in text[]
  pass_length = length(pass);
  text_length = length(text);
  int     sol; //output character

  FILE   *nom;

  nom = fopen(name, "w");

  for(textPosition = 0; textPosition < text_length; textPosition++) {
    if(passPosition == pass_length) {
      passPosition = 0;
    }
    if(x == false) {
      sol = text[textPosition] + pass[passPosition];
      while(sol > 126) {
sol -= 94;
      }
    } else {
      sol = text[textPosition] - pass[passPosition];
      while(sol < 32) {
sol += 94;
      }
    }
    passPosition++;
    fputc(sol, nom);
  }
  fclose(nom);
}

/*
 *Title: length
 *Description: It count logic string length
 *@param l[]: string
 *@return m: lenght
 */
int length(char l[]) {
  int     m = 0;
  while(l[m] != '\0') {
    m++;
  }
  return m;
}
y del methods.c es
Código:
#include "data.h"

/*
 *Title: showFile
 *Description: Print in screen a file
 *@param n[]:filename
 *@param tam: length of file
 */
void showFile(char n[],int tam){
char f[tam];//output string

FILE *show;
show = fopen(n, "r");
fgets(f,tam,show);
printf("%s\n",f);
}

/*
 *Title: helpbox
 *Description: Show the help menu
 */
void helpbox(){
printf("\n");
printf("\tcryptoJKA from JKA Network - Version: %s\n", VERSION);
printf("\n");
printf("\tThe text must be between ASCII 32 and ASCII 125\n\n");
printf("\tOptions:\n");
printf("\t -f [file_name],\tinput file\n");
printf("\t -o [file_name],\toutput file (default : crypt.out)\n");
printf("\t -p [text],\t\tpassword (default: pass)\n");
printf("\t -t [text],\t\ttext (default: text)\n\t\t\t\t\tIf you put -f and -t, text have preference\n");
printf("\t -e,\t\t\tencrypt mode\n");
printf("\t -d,\t\t\tdecrypt mode\n");
printf("\t -r [number],\t\twith random generation [number of character]\n");
printf("\t -h,\t\t\tshow this box\n");
printf("\t -v, --version,\t\tshow version\n\n");
printf("\t Examples:\n\n");
printf("\t\tcryptojka -e -t \"Example text\" -p password -o file_name -r 600\n");
printf("\t\tcryptojka -d -f file_name -p password\n\n");
}

/*
 *Title: random
 *Description: It generates random text between ASCII 32 and 126
 *@param tam: max length of string
 *@param name[]: output name
 */
void rangen(int tam, char name[]){
FILE *out_text;

out_text = fopen(name, "a");

int p;//Generated num
int m;//Relative position
for(m=0;m<tam;m++){
p=(rand() % 95)+32; //p is between 32 and 126
fputc(p, out_text);
}
fclose(out_text);
}


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: LaiaxanIV en 29 Marzo 2016, 19:10 pm
Lo que has implementado es un algoritmo ya existente llamado Vigènere. Este algoritmo de cifrado es bastante fácil de descifrar. Lo único que se tiene que hacer es buscar patrones repetidos en el texto cifrado, así puedes conocer la longitud de la clave.
A partir de ahí, se crea una matriz de N x M, donde N es la longitud de la clave y M longitud del texto cifrado/N.
Así, finalmente, se empieza a jugar con las frecuencias de las letras que aparecen en las columnas de esta matriz y a compararlas con el idioma del texto cifrado -si no lo conoces vas probando :P - (ej.: en inglés la letra más repetida es la e, después la t, la a...) y ya lo tienes.
Hace poco hice una práctica que iba de eso. Lamentablemente perdí el código por un error al borrar la carpeta del github donde lo teníamos.


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: kub0x en 30 Marzo 2016, 00:29 am
Vigènere depende del tamaño de clave, básicamente si el tamaño de clave es inferior al tamaño del texto a cifrar (plaintext) se reutilizará la misma clave, pudiendo observar patrones en el ciphertext, deduciendo así la clave.

Si por algún motivo el atacante tiene en su poder ciertas partes del plaintext, le sería mucho más fácil obtener ciertas partes de la clave, por lo que podría deducir aún más carácteres del plaintext. Remarcar que si el tamaño de clave es igual al tamaño del plaintext se equipararía con un One-Time-Pad (se podría decir que a cada carácter una clave).

Saludos!


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: JoseluCross en 30 Marzo 2016, 02:24 am
No sabía que el cifrado tenía nombre, gracias por aclararlo.

Conociendo el problema de la estadistica implementamos un sistema para añadir caracteres aleatorios al final del texto cifrado, obviamente no sirve de nada si el atacante conoce la cantidad de caracteres son aleatorios porque siempre se colocan al final, pero si esto es desconocido ¿Es más seguro? Y otra pregunta, ¿cómo se buscan los patrones que mencionáis para ver repeticiones en el texto cifrado? y reconociendo los patrones ¿como tengo que aplicar el criptoanalisis existiendo 94 caracteres posibles? Muchas gracias nuevamente por todas sus opiniones.


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: LaiaxanIV en 30 Marzo 2016, 16:27 pm
Aunque se desconociese el número de caracteres aleatorios se podría usar la misma estrategia para descifrar el mensaje, lo único que será más costoso ya que me puedes variar el orden de repeticiones. La única manera de hacerlo completamente seguro es que la longitud de la clave sea la misma longitud que la del texto (esto es un estándar del NIST lo que ahora no me acuerdo bien del nombre).
Te pongo un ejemplo:
Clave: "HOLA"
Mensaje: este es un mensaje super secreto y nadie nunca lo va a descifrar
Cifrado: lgee lg fn tsyshxp sbdpr zsnrlhz y uooil bfnjo wo co l dlgnimflr

A simple vista, se observa como la letra l se repite cada 4 posiciones. Seguro que alomejor otras letras tambien (ten en cuenta que en textos muy largos las repeticiones llegan a ser de mas letras cosa que te asegura más precisión).

lgee
lgfn
tsys
hxps
bdpr
zsnr
lhzy
uooi
lbfn
jowo
cold
lgni
mflr


Supongamos que se que es español, por lo tanto las frecuencias son E,A,O,S,N,R.

Una vez tienes esto, solo tienes que contar por columnas la letra que mas aparece. En el primer caso es la l que aparece 5 veces. Pues para conseguir una E con una L utilizamos la H. Para conseguir la A utilizamos una L.
La segunda columna estamos entre S y G que aparecen tres veces. Vamos a elegir la S porque es la buena (jijijiji) tendrías que probar xD. Por tanto para obtener la E con S... Una O!
Seguiríamos así hasta haber hecho las 4 columnas.

Ten en cuenta que no siempre la E es la letra indicada, tendremos que usar la A, la O, la S... Dependerá un poco del texto. Fíjate que la última columna la letra más repetida es la R que es la 6a letra en el orden de frecuencias, para llegar a obtener la A tendríamos que haber pasado por las otras. Así tendremos que probar con unas cuantas claves, descifraremos el texto con todas las claves y elegiremos el bueno!


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: JoseluCross en 30 Marzo 2016, 17:29 pm
Si, lo veo, pero mi cifrado no es vigenere puro, funciona con ascii(32-126) no con el alfabeto por lo que una mayúscula y una minuscula bajo la misma letra son distintas, los espacios tambien se codifican, las comas, los puntos etc. En ese caso cual es la forma de vulnerar el cifrado. Por ejemplo

Citar
OdbHhVaa__lPO_aDTVlV_aSU]VQUOe]aco\DNZSaXf\FKoZRhgOaKoRH]TWI\R`
Sería "este es un mensaje super secreto y nadie nunca lo va a descifrar" con la contraseña HOLA

Muchas gracias, estoy aprendiendo muchisimo


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: LaiaxanIV en 30 Marzo 2016, 18:08 pm
Parece que se haría igual, solo tendrías que modificar el alfabeto que se usa, incluso te podría decir que me lo pones más facil ya que los espacios permiten detectar la longitud de la clave muy facilmente. Ahora solo variaria la frecuencia (no se si el espacio sería más frecuente). Además al diferenciar entre mayúsculas y minúsculas permitiria conocer aún mejor el texto, ya que un punto indica mayúscula y, al detectar una mayúscula se podria saber si el caracter anterior es un punto...
Como ves hay muchas cosas a tener en cuenta.


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: JoseluCross en 30 Marzo 2016, 19:25 pm
Ok, entonces una expansión del alfabeto no lo haría mas seguro. Una cosa que se me ocurre, quizás es una tontería de principiante pero total, ya lo soy. ¿Si cambio de manera aleatoria los espacios por caracteres que no afectarían a la interpretación del texto como "-" "_" "~" o el mismo espacio afectaría a la búsqueda de patrones con el espacio o no? Gracias nuevamente, y lo siento si lo que pregunto puede sonar estúpido, soy muy nuevo en esto.


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: kub0x en 30 Marzo 2016, 19:39 pm
JoseluCross he de comunicarte que tu cifrado tiene una vulnerabilidad en la forma que cifra los espacios, por lo que puedo deducir facilmente la clave de cifrado, me explico poniendo como ejemplo el que tu has puesto antes:

clave: hola
texto plano (plaintext): este es un mensaje super secreto y nadie nunca lo va a descifrar
texto cifrado (ciphertext): OdbHhVaa__lPO_aDTVlV_aSU]VQUOe]aco\DNZSaXf\FKoZRhgOaKoRH]TWI\R`
alfabeto:  (espacio)!"#$%&'()*+´-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~

Vamos paso por paso, cogemos las primeras cuatro letras -> "este" y vemos como cifra:

'e' corresponde a O mediante 'h'
's' corresponde a d mediante 'o'
't' corresponde a b mediante 'l'
'e' corresponde a H mediante 'a'

hasta aquí todo bien, ahora toca el espacio entre "este" y "es"

(espacio) corresponde a 'h' mediante 'h' (está dándonos parte de la clave)

Sigo...

'e' corresponde a V mediante 'o'
's' corresponde a 'a' mediante 'l'

Toca otro espacio entre "es" y "un"

(espacio) corresponde a 'a' mediante 'a' (sigue dándonos parte de la clave)

y así sucesivamente hasta obtener la clave entera o parte de la clave "hola".

Simplemente he analizado el texto en el notepad mirando el mapeo entre ciphertext y plaintext, un analisis estádistico en base a tu alfabeto sería lo ideal.

Saludos!


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: LaiaxanIV en 30 Marzo 2016, 19:51 pm
Citar
JoseluCross he de comunicarte que tu cifrado tiene una vulnerabilidad en la forma que cifra los espacios.

Este problema existirá siempre y cuando tu algoritmo de cifrado use operaciones con elementos neutros. Es decir, al sumar 0 siempre tendrás la clave. Lo mismo ocurre en el caso del Vigènere con la A.
No se si eso llega a afectar de gran manera ya que tampoco conoces la posición de los espacios. Lo que, al ser el caracter más repetido, solo haria falta mirar los carácteres mas repetidos en el texto cifrado para tener una idea de los caracteres que forman la clave.


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: JoseluCross en 30 Marzo 2016, 20:06 pm
JoseluCross he de comunicarte que tu cifrado tiene una vulnerabilidad en la forma que cifra los espacios, por lo que puedo deducir facilmente la clave de cifrado, me explico poniendo como ejemplo el que tu has puesto antes:
Saludos!
No me había fijado, obviamente necesitas saber donde están pero una ves deducido ya se tiene el valor. Si consideramos lo que planteaba de cambiar los espacios de manera aletoria entre otros caracteres que no perjudiquen a la interpretacion del texto esto no debería ocurrir no? y si tenemos en cuenta lo del texto aleatorio al final quizas los patrones sean algo mas dificiles, aunque claro, al estar al final con ignorar los patrones mas cercanos al final...
Muchas gracias por la anotación. La verdad es se nota lo mucho que sabéis  ;-). Gracias


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: LaiaxanIV en 30 Marzo 2016, 20:37 pm
Casi parece mejor no cifrar los espacios xD
Si conozco donde van los espacios podré saber la longitud de las palabras. Si las conozco sabre que por ejemplo palabras de 2 de longitud contendrán una vocal, si es solo de 1 es probable que sea una vocal o una y...
Recuerda que cuanta más información me des, más fácil será romper el algoritmo.


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: JoseluCross en 30 Marzo 2016, 21:04 pm
Casi parece mejor no cifrar los espacios xD
Si conozco donde van los espacios podré saber la longitud de las palabras. Si las conozco sabre que por ejemplo palabras de 2 de longitud contendrán una vocal, si es solo de 1 es probable que sea una vocal o una y...
Recuerda que cuanta más información me des, más fácil será romper el algoritmo.
Si no los cifro no daría ya la información de donde están? o lo que me propones es que los borre?


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: LaiaxanIV en 31 Marzo 2016, 09:03 am
Si no los cifro no daría ya la información de donde están? o lo que me propones es que los borre?
JAJAJJAJA
Tienes razón xD Si no los cifras aparecen igual :^D Nada se me ha ido la pinza.
Borrarlos... Bueno, puede que modifiques el texto asi que no me parece una buena opción.
Para mejorar la seguridad yo lo que haría seria modificar el texto de alguna manera, a partir de la clave, para intentar cambiar el patrón de repeticiones.
Por ejemplo, si la palabra es HOLA coges el valor de la primera letra (en este caso H) y añades un valor a esa posición, y así para todos los caracteres. Almenos haces más difícil encontrar patrones y el descifrado es relativamente sencillo.


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: kub0x en 31 Marzo 2016, 17:15 pm
Te dejo un post muy interesante sobre el cracking de múltiples cifrados de substitución, lo encuentro interesante pues tu cifrado es similar a las características aquí descritas, el post está en inglés, y la comunidad es muy extensa (actualmente soy miembro y hago mis preguntillas ahí). Segro que te ayuda a mejorar la seguridad y a emprender un criptoanálisis sobre el mismo.

https://crypto.stackexchange.com/questions/3826/possible-ways-to-crack-simple-substitution-ciphers

Si tienes alguna duda no dudes en comentarla.

Saludos!


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: arget en 31 Marzo 2016, 23:21 pm
No he mirado tu código (pereza jeje), pero si lo que haces es simplemente implementar ASCII 32-126 será igual pero empleando un alfabeto más grande, cuál es el carácter del ASCII que más se repite en inglés y en castellano?, la 'e' y después la 'E'.
De todas formas el método que te ha dicho Laiaxan no es válido contra el cifrado de Vigenère. Vigenère es polialfabético, por tanto un carácter no será siempre el mismo en el criptograma, del mismo modo, un carácter en el criptograma no representará siempre al mismo carácter. Sin embargo tiene su técnica similar. En textos largos con claves de cierto tamaño aparecen en el criptograma cadenas que se repiten cada cierto tiempo, esas cadenas, si suponemos que no son coincidencia, son zonas en las que un texto cifrado coincide de nuevo con la clave, veamos (clave "ABCDEFG"):
Código:
asdasdasdasdEJEMPLOasdasdasdEJEMPLOasdasdasda...
ABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCD...
En el criptograma se verá que en donde EJEMPLO coincide con EFGHABC se repetirán los caracteres cifrados. Con esto podemos saber que la distancia entre repetición y repetición es un múltiplo de la longitud de la clave. Esto se evita mediante el one-time-pad, que es la generación de una clave aleatoria de la longitud del texto a cifrar.


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: AlbertoBSD en 1 Abril 2016, 06:50 am
Buen dia pues hice un pequeño programa para tu algoritmo.

La idea que tenia no a funcionado.

El enfoque era estadístico, lo que hice fue generar N arreglos de Enteros donde N es igual al numero de caracteres del mensaje.

El primer arreglo[0] es de longitud 1
El segundo arrega[1] es de longitud 2
y asi sucesivamente.

Guarde las sumas de los valores ascii de cada caracter en los arreglos. Ademas de contar cuantas veces se sumaba en cada caracter en cada casilla.

Saque los promedios y las desviaciones estandar ademas. saque el promedio de cada arreglo y las desviaciones estandar de las desviaciones estandar valga la redundancia...

Mi idea era ver como cambiaban las desviaciones estandar y me imaginaba que en los puntos de inflexion estaría la pista.

Curiosamente en algunos ejemplos el primer punto de inflexion coincidencia con la longitud de la contraseña, pero en otros no lo hacia.

Codigo:

Código
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<errno.h>
  5. #include<sys/stat.h>
  6.  
  7. off_t fsize(const char *filename);
  8. unsigned char max(unsigned char item,unsigned char mx);
  9. unsigned char min(unsigned char item,unsigned char mn);
  10.  
  11. int main() {
  12. int **sums;
  13. int **counts;
  14. float **diff;
  15. float **promedios;
  16. float **desviacion;
  17. float *sumdesviaciones;
  18. float *promedioDesviaciones;
  19. float *diffdesviaciones;
  20. float *desviacion2;
  21. FILE *file;
  22. char *buffer;
  23. float temp;
  24. int l,i,j,k;
  25. file = fopen("salida.txt","r");
  26. if(file) {
  27. l = fsize("salida.txt");
  28. buffer = calloc(l+1,sizeof(char));
  29. fread(buffer,sizeof(char),l,file);
  30. fclose(file);
  31. sums = calloc(l,sizeof(int*));
  32. counts = calloc(l,sizeof(int*));
  33. diff = calloc(l,sizeof(float*));
  34. promedios = calloc(l,sizeof(float*));
  35. desviacion = calloc(l,sizeof(float*));
  36. sumdesviaciones = calloc(l,sizeof(float));
  37. promedioDesviaciones = calloc(l,sizeof(float));
  38. diffdesviaciones = calloc(l,sizeof(float));
  39. desviacion2 = calloc(l,sizeof(float));
  40. i = 0;
  41.  
  42. while(i < l) {
  43. sums[i] = calloc(i+1,sizeof(int));
  44. counts[i] = calloc(i+1,sizeof(int));
  45. diff[i] = calloc(i+1,sizeof(float));
  46. promedios[i] = calloc(i+1,sizeof(float));
  47. desviacion[i] = calloc(l,sizeof(float));
  48. i++;
  49. }
  50.  
  51. //rellenar array de sumas
  52. j = 0;
  53. while(j < l) {
  54. k =0;
  55. while(k < l) {
  56. //printf("Procesando sums[%i][%i]\n",j,(k % (j+1)));
  57. sums[j][k % (j+1)] += buffer[k];
  58. counts[j][k % (j+1)] +=1;
  59. k++;
  60. }
  61. j++;
  62. }
  63. //mostramos las sumas y los contadores
  64. i=1;
  65. j=0;
  66. while(j < l) {
  67. k =0;
  68. while(k < i) {
  69. //printf("sums[%i][%i] = %i\n",j,k,sums[j][k]);
  70. //printf("counts[%i][%i] = %i\n",k,i,counts[j][k]);
  71. k++;
  72. }
  73. i++;
  74. j++;
  75. }
  76. //calcular promedios
  77. i=1;
  78. j=0;
  79.  
  80. while(j < l) {
  81. k =0;
  82. while(k < i) {
  83. promedios[j][k] = ((float)sums[j][k])/((float)counts[j][k]);
  84. //printf("promedios[%i][%i] = %f\n",j,k,promedios[j][k]);
  85. k++;
  86. }
  87. i++;
  88. j++;
  89. }
  90. //calcular Diferencias
  91. j = 0;
  92. while(j < l) {
  93. k =0;
  94. while(k < l) {
  95. temp = promedios[j][k % (j+1)] - buffer[k];
  96. if(temp < 0.0) {
  97. temp = -1.0 *temp;
  98. }
  99. diff[j][k % (j+1)] += temp;
  100. k++;
  101. }
  102. j++;
  103. }
  104. //calcular desviacion
  105. i=1;
  106. j=0;
  107. while(j < l) {
  108. k =0;
  109. while(k < i) {
  110. desviacion[j][k] = diff[j][k]/counts[j][k];
  111. //printf("desviacion[%i][%i] = %f\n",j,k,desviacion[j][k]);
  112. k++;
  113. }
  114. i++;
  115. j++;
  116. }
  117.  
  118. //calcular suma desviaciones
  119. i=1;
  120. j=0;
  121. while(j < l) {
  122. k =0;
  123. while(k < i) {
  124. sumdesviaciones[j]+= desviacion[j][k];
  125. k++;
  126. }
  127. promedioDesviaciones[j] =  sumdesviaciones[j]/i;
  128. printf("promedio desviacion[%i] = %f\n",j,promedioDesviaciones[j]);
  129. i++;
  130. j++;
  131. }
  132. //calcular differencia de desviaciones
  133. i=1;
  134. j=0;
  135. while(j < l) {
  136. k =0;
  137. while(k < i) {
  138. diffdesviaciones[j]+= promedioDesviaciones[j] - desviacion[j][k];
  139. k++;
  140. }
  141. desviacion2[j] = diffdesviaciones[j]/(float)k;
  142. printf("desviacion2[%i] = %f\n",j,desviacion2[j]);
  143. i++;
  144. j++;
  145. }
  146.  
  147. printf("l : %i\n",l);
  148. }
  149. return 0;
  150. }
  151.  
  152. unsigned char max(unsigned char item,unsigned char mx) {
  153. return (item >= mx)? item:mx;
  154. }
  155.  
  156. unsigned char min(unsigned char item,unsigned char mn) {
  157. return (item <= mn)? item:mn;
  158. }
  159.  
  160. off_t fsize(const char *filename) {
  161. struct stat st;
  162. if (stat(filename, &st) == 0)
  163. return st.st_size;
  164. fprintf(stderr, "Cannot determine size of %s: %s\n",filename, strerror(errno));
  165. return -1;
  166. }
  167.  
  168.  


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: kub0x en 1 Abril 2016, 09:32 am
Muy buenas JoseluCross,

he probado tus dos vertientes del algoritmo de cifrado, la primera dónde simplemente reiniciabas el contador de la clave para cifrar de N en N bloques (donde N es el tamaño de clave) y la segunda la cual incrementas el valor de cada carácter de la clave por cada bloque de tamaño N.

Supongo que en la segunda vertiente intentabas arreglar el tema de los espacios.

Problemas en primera versión: Los espacios al ser sumados en la clave pueden exceder el tamaño 126, por lo que reducirías en 94 su peso. Cuando eso no sucede, simplemente basta con restar a todo el ciphertext el número 32 para obtener los caracteres de la clave.

Problemas en segunda versión: Aquí cuando el bloque a cifrar se acaba, a parte de reiniciar el contador "passPosition", incrementas en uno el peso de cada carácter de la clave. Por lo que si el cracker conoce el tamaño de clave, puede dividir el texto en bloques relacionados con la clave, y contar los incrementos, todo ello en zero index. Un ejemplo sería:

HOLA (pass) este es un mensaje super secreto y nadie nunca lo va a descifrar (plaintext). 64 length el plaintext, 4 length la pass -> 16 bloques, en zero index 15, por lo tanto 15 incrementos por caracter en la clave.

Notése que en ambos casos, aún restando 94, sería fácil obtener el password.

Te dejo dos capturas, la primera corresponde a la V 1.0 y la segunda a la V 2.0 (el code del github):

(https://i.imgur.com/IqPTTLL.png)

(https://i.imgur.com/kOLs0Qy.png)

Fíjate como en la segunda hasta se aprecia "HOLA" de seguida. Fíjate que los caracteres alfábeticos en su mayoría son H, O, L y A (no sería muy díficil deducir incluso a ojo la clave) alguno que otro alfabético hay, y el resto son númericos/símbolos.
Simplemente habría que restar a cada carácter del ciphertext (texto cifrado) 32 y 15 para obtener la clave en cuestión.

No he querido meterme en análisis estadístico, pero bueno no creo que me tomara mucho montarme un escenario en el lenguaje R.

Saludos!


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: JoseluCross en 1 Abril 2016, 15:54 pm
Veo por donde vas, me a costado pillarlo pero bueno. Yo cuando hice el arreglo para cambiar la contraseña lo hice pensando en reducir la probabilidad de reconocer patrones y poder deducir el tamaño de la contraseña, claro que pierde toda fuerza una vez conocido el tamaño.
Una cosa que no entiendo ¿por qué 96? son 94 los caracteres del rango ascii que uso.

Buen dia pues hice un pequeño programa para tu algoritmo.

La idea que tenia no a funcionado.

El enfoque era estadístico, lo que hice fue generar N arreglos de Enteros donde N es igual al numero de caracteres del mensaje.

El primer arreglo[0] es de longitud 1
El segundo arrega[1] es de longitud 2
y asi sucesivamente.

Guarde las sumas de los valores ascii de cada caracter en los arreglos. Ademas de contar cuantas veces se sumaba en cada caracter en cada casilla.

Saque los promedios y las desviaciones estandar ademas. saque el promedio de cada arreglo y las desviaciones estandar de las desviaciones estandar valga la redundancia...

Mi idea era ver como cambiaban las desviaciones estandar y me imaginaba que en los puntos de inflexion estaría la pista.

Curiosamente en algunos ejemplos el primer punto de inflexion coincidencia con la longitud de la contraseña, pero en otros no lo hacia.
Muy interesante, lo probaré, muchas gracias.


Título: Re: Sistema de cifrado por lote de texto plano
Publicado por: kub0x en 1 Abril 2016, 20:23 pm
Corregido, eran 94, tienes razón. Era tarde y me equivoqué jajaja pero bueno el tema queda ahí. Haz pruebas sobre los casos que he presentado e intenta añadir alguna protección extra para que podamos ayudarte a securizarlo un poco más.

Te recomiendo leer sobre cifrados por bloque y álgebra modular, pues son principios en los que se basan algunos de los cifrados estándar modernos.

Saludos!