Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Kaxperday en 22 Agosto 2015, 20:08 pm



Título: Encriptador de C++ Rijndael ayuda
Publicado por: Kaxperday en 22 Agosto 2015, 20:08 pm
Hola, hace unos dias estuve buscando algo para cifrar cadenas de texto incluso un archivo completo, y encontré este encriptador de código abierto que incluí en mi proyecto.

Funciona, pero cifra bloques de 8, 16, y 24 carácteres, luego si lo que quieres cifrar no es múltiplo de eso falla.

¿que solución puedo aportar?.

Código
  1. string encriptar_primera(string entrada)
  2. {
  3. try
  4. {
  5. encriptador_1 oRijndael;
  6. string retorno;
  7. oRijndael.MakeKey(ENCLAVE_PRIMERA, encriptador_1::sm_chain0, 24, 24);
  8. while (entrada.length() % 24 != 0)
  9. entrada += 'Z';
  10. for (int i = 0; i < entrada.length(); i = i + 24){
  11. char *salida = new char[entrada.length()]();
  12. salida = NULL;
  13. string bloque = entrada.substr(i, 24);
  14. oRijndael.EncryptBlock(bloque.c_str(), salida);
  15. retorno += salida;
  16. }
  17. cout << ": " << retorno << endl;
  18. return retorno;
  19. }
  20. catch (exception& roException)
  21. {
  22. return "";
  23. }
  24. }

Probé a añadirle 'Z' hasta que sea múltiplo pero creo que la llamada Encrypt hace Xor y por eso no funciona, ¿qué puedo hacer para trabajar con ello sin problemas si quiero cifrar cadenas no necesariamente multiplos de 24 sin perder datos.

Saludos.


Título: Re: Encriptador de C++ Rijndael ayuda
Publicado por: engel lex en 22 Agosto 2015, 20:14 pm
Igual que aes (que es basado en rijandel) rellenas con /0 al final hasta llegar a el multiplo


Título: Re: Encriptador de C++ Rijndael ayuda
Publicado por: Kaxperday en 22 Agosto 2015, 20:19 pm
Jejeje, curioso eso fue lo primero que hice y se me ocurrió pero parecio no dar resultado ahora pongo las pruebas.

Saludos.

Código:

Código
  1. string encriptar_primera(string entrada)
  2. {
  3. try
  4. {
  5. encriptador_1 oRijndael;
  6. char *salida = new char[entrada.length()]();
  7. oRijndael.MakeKey(ENCLAVE_PRIMERA, encriptador_1::sm_chain0, 24, 24);
  8. while (entrada.length() % 24 != 0)
  9. entrada+='\0';
  10. oRijndael.Encrypt(entrada.c_str(), salida, entrada.length(), encriptador_1::CBC);//falla encript
  11. cout << ": " << salida << endl;
  12. return string(salida);
  13. }
  14. catch (exception& roException)
  15. {
  16. return "";
  17. }
  18. }
  19.  
  20. string desencriptar_primera(string entrada)
  21. {
  22. try
  23. {
  24. encriptador_1 oRijndael;
  25. char *salida = new char[entrada.length()]();
  26. oRijndael.MakeKey(ENCLAVE_PRIMERA, encriptador_1::sm_chain0, 24, 24);
  27. while (entrada.length() % 24 != 0)
  28. entrada += '\0';
  29. oRijndael.Decrypt(entrada.c_str(), salida, entrada.length(), encriptador_1::CBC);
  30. cout << ": " << salida << endl;
  31. return string(salida);
  32. }
  33. catch (exception& roException)
  34. {
  35. return "";
  36. }
  37. }
  38.  
  39.  

Ahora ejecuto.. ahi están las principales funciones se muestra la cadena original, se muestra luego la cadena cifrada, y luego la descifrada de la que solo se descifran los 48 primeros caracteres.

Salida:

Citar
Presione una tecla para continuar . . .
CPcqGW51VRuFPRzAxwEM7mgF5BDu2xspuP4DtANxnyFtCn4jPKItqWCAdJn6QTMTgH0wSWCMQOKA3H6OxDNJOWH2PIWCy3k79QJw : ╣ܸ¾▀fºYb┼‗     $Û4░sÍSÑ█ñmÿ`╚XK¥8­Q+òHZ;çfª?>¥YR┼öÏ\RR·7eü8MȨ╝¬i─ÛèuÙÏ  ã¼ã«Xc╣
1Presione una tecla para continuar . . .
: CPcqGW51VRuFPRzAxwEM7mgF5BDu2xspuP4DtANxnyFtCn4jPKItqWCAdJn6QTMTgH0wSWCM>▄n£¶°cN$│║©QF©
1Presione una tecla para continuar . . .

Saludos.

Edito: Otra prueba de que no rula:

Código
  1. encriptador_1 e3;
  2. string entrada = "0q9an9yv7134nyc8q09wrucy09q349y9q34y7n3wwwwwwwwwwwwwwww9999";
  3. e3.MakeKey(ENCLAVE_PRIMERA, encriptador_1::sm_chain0, 24, 24);
  4. while (entrada.length() % 24 != 0)
  5. entrada += '\0';
  6. char *salida = new char[entrada.length()]();
  7. char *salidas = new char[entrada.length()]();
  8. cout << "entrada: " << entrada.c_str() << endl;
  9. e3.EncryptBlock(entrada.c_str(),salida);
  10. cout << "cifrada: " << salida << endl;
  11. e3.DecryptBlock(salida, salidas);
  12. cout << "salida: " << salidas << endl;

Muestra:

Citar
entrada: 0q9an9yv7134nyc8q09wrucy09q349y9q34y7n3wwwwwwwwwwwwwwww9999
cifrada: Sî$+│kz
salida: 0q9an9yv7134nyc8q09wrucy
Presione una tecla para continuar . . .

Falta el resto.


Título: Re: Encriptador de C++ Rijndael ayuda
Publicado por: BlackZeroX en 22 Agosto 2015, 22:19 pm
AES/Rindael te cifra por bloques de bits...

Si es un AES-128 te cifrara solo 16 bytes por lo cual en una cadena como la siguiente:

"Hola Mundo Cruel esta es una cadena de jodida longitud solo para nada"

Se le debe pasar de 16 caracteres en 16 caracteres a AES-128.

AES-128("Hola Mundo Cruel")
AES-128("" esta es una cad")
AES-128(""ena de jodida lo")
AES-128(""ngitud solo para")
AES-128("" nada\0\0\0\0\0\0\0\0\0\0\0")

Si fuera:

AES-64: 8 caracteres
AES-128: 16 caracteres
AES-192: 24 caracteres
AES-256: 32 caracteres
...
AES-1024: 128 caracteres
AES-2048: 256 caracteres
...

Es decir el numero entre 8 bits = cantidad de caracteres... 128/8 = 16, ... 2048/8 = 256...

El resto se llena de bits 0 o bytes 0 = \0

El resultado del cifrado se concatena y listo... para descifrarlo es el mismo proceso... se busca el múltiplo y se remueven al final los bits 0... // bytes 0...

Saludos!.


Título: Re: Encriptador de C++ Rijndael ayuda
Publicado por: do-while en 23 Agosto 2015, 20:10 pm
¡Buenas!

El problema creo que lo tienes aquí:
Código
  1. oRijndael.Decrypt(entrada.c_str(), salida, entrada.length(), encriptador_1::CBC);
  2.  

entrada.length() te dirá cuantos caracteres hay antes del primer caracter nulo. Puedes almacenar la entrada en un vector<char>  y añadir ceros para luego utilizar la función size() sobre el vector y así obtener el número real de elementos que tenga, incluyendo los ceros que hayas añadido.

¡Saludos!


Título: Re: Encriptador de C++ Rijndael ayuda
Publicado por: Kaxperday en 24 Agosto 2015, 01:04 am
Gracias, por las respuestas me pondré a ello entre hoy y mañana a ver si lo hago funcionar ya bien :). Si eso subiré los progresos actualizados.  ;D

Edito: La verdad no me parece buena idea hacer un vector de char, además eso sería muy raro, supongo que sería mejor usar char* ... etc. O hacer una funcion que cuente hasta el ultimo \0, no se ya lo pensaré :P.

Saludos.

Edito: Al parecer no es cierto lo de string.length, acabo de hacer una comprobación.

Antes de cifrar la cadena mide 101 caracteres, y despues 120 (tras añadir los \0 hasta llegar a multiplo de 24) y ambas veces es medido por length, asi que no es cierto.

Por otro lado sigo en ello.

Creo que el error puede estar en que el archivo lo estoy leyendo en modo texto, en vez en modo binario pues al escribir la candena de 120 caracteres, luego me lee una de 82 que al descifrar da una de 96 porque la hago multiplo, pero desde el primer momento al releer el archivo para desencriptarlo deberían de salir los caracteres exactos de la cadena cuando escribi en el que son 120. Y sin \0 al menos 101.

Código
  1. string encriptar_primera(string entrada)
  2. {
  3. try
  4. {
  5. encriptador_1 oRijndael;
  6. char *salida = new char[150]();
  7. oRijndael.MakeKey(ENCLAVE_PRIMERA, encriptador_1::sm_chain0, 24, 24);
  8. cout << "tam antes" << entrada.length() << endl;
  9. while (entrada.length() % 24 != 0)
  10. entrada += '\0';
  11. cout << "tam despues" << entrada.length() << endl;
  12. oRijndael.Encrypt(entrada.c_str(), salida, entrada.length(), encriptador_1::CBC);//falla encript
  13. cout << "tam salida" << string(salida).length() << endl;
  14. cout << ": " << salida << endl;
  15. return string(salida);
  16. }
  17. catch (exception& roException)
  18. {
  19. return "";
  20. }
  21. }
  22.  
  23. string desencriptar_primera(string entrada)
  24. {
  25. try
  26. {
  27. encriptador_1 oRijndael;
  28. char *salida = new char[150]();
  29. oRijndael.MakeKey(ENCLAVE_PRIMERA, encriptador_1::sm_chain0, 24, 24);
  30. cout << "tam entrada " << entrada.length() << endl;
  31. while (entrada.length() % 24 != 0)
  32. entrada += '\0';
  33. oRijndael.Decrypt(entrada.c_str(), salida, entrada.length(), encriptador_1::CBC);
  34. cout << "tam salida: " << string(salida).length() << endl;
  35. cout << ": " << salida << endl;
  36. return string(salida);
  37. }
  38. catch (exception& roException)
  39. {
  40. return "";
  41. }
  42. }

Salida:

Citar
CPcqGW51VRuFPRzAxwEM7mgF5BDu2xspuP4DtANxnyFtCn4jPKItqWCAdJn6QTMTgH0wSWCMQOKA3H6OxDNJOWH2PIWCy3k79QJw he leido 101
tam antes101
tam despues120
tam salida120
: ╣ܸ¾▀fºYb┼‗  $Û4░sÍSÑ█ñmÿ`╚XK¥8­Q+òHZ;çfª?>¥YR┼öÏ+~$PÂ1û■Ë-í╩Ö×┼╣ç/┤âÀn¨\RR·7eü8MȨ╝¬i─ÛèuÙÏ  ã¼ã«Xc╣
 voy a escribir 120encriptadodesencriptando..he leido 82
tam entrada 82
tam salida: 96
: CPcqGW51VRuFPRzAxwEM7mgF5BDu2xspuP4DtANxnyFtCn4jPKItqWCAdJn6QTMTgH0wSWCM>▄n£¶°cN$│║©QF©

No entiendo porque escribo 120 caracteres en el archivo (cifrados) y luego al leer me salen que tengo 82, ¿alguien me podría decir porque?

Se verifica que el tamaño del archivo es de 120 bytes, el problema está en la posterior lectura del archivo.

Saludos.

Edito: Parece que el camino está por usar un vector char para leer todos los caracteres como muestra este hilo:

http://codereview.stackexchange.com/questions/22901/reading-all-bytes-from-a-file

Tengo la función que permite leer todos los bytes del fichero y pasarlo a string, ahora si podríamos desencriptarlo:

Código
  1. string lee_fichero(string archivo)
  2. {
  3. string salida;
  4. ifstream ifs(archivo.c_str(), ios::binary | ios::ate);
  5. ifstream::pos_type pos = ifs.tellg();
  6. vector<char>  result(pos);
  7. ifs.seekg(0, ios::beg);
  8. ifs.read(&result[0], pos);
  9. ifs.close();
  10. for (int i = 0; i < result.size(); i++)
  11. salida += result[i];
  12. return salida;
  13. }

THIS PROBLEM WAS SOLVED

Citar
CPcqGW51VRuFPRzAxwEM7mgF5BDu2xspuP4DtANxnyFtCn4jPKItqWCAdJn6QTMTgH0wSWCMQOKA3H6OxDNJOWH2PIWCy3k79QJw he leido 101
tam antes101
tam despues120
tam salida120
: ╣ܸ¾▀fºYb┼‗  $Û4░sÍSÑ█ñmÿ`╚XK¥8­Q+òHZ;çfª?>¥YR┼öÏ+~$PÂ1û■Ë-í╩Ö×┼╣ç/┤âÀn¨\RR·7eü8MȨ╝¬i─ÛèuÙÏ  ã¼ã«Xc╣
 voy a escribir 120
╣ܸ¾▀fºYb┼‗    $Û4░sÍSÑ█ñmÿ`╚XK¥8­Q+òHZ;çfª?>¥YR┼öÏ+~$PÂ1û■Ë-í╩Ö×┼╣ç/┤âÀn¨\RR·7eü8MȨ╝¬i─ÛèuÙÏ  ã¼ã«Xc╣
encriptadodesencriptando..okhe leido 120
╣ܸ¾▀fºYb┼‗    $Û4░sÍSÑ█ñmÿ`╚XK¥8­Q+òHZ;çfª?>¥YR┼öÏ+~$PÂ1û■Ë-í╩Ö×┼╣ç/┤âÀn¨\RR·7eü8MȨ╝¬i─ÛèuÙÏ  ã¼ã«Xc╣
tam entrada 120
tam salida: 101
: CPcqGW51VRuFPRzAxwEM7mgF5BDu2xspuP4DtANxnyFtCn4jPKItqWCAdJn6QTMTgH0wSWCMQOKA3H6OxDNJOWH2PIWCy3k79QJw 

Trabajando con un vector de char para leer el archivo que no parece a primeras buena idea, pero de primeras funciona, si encuentro algo mejor ya lo cambiare.

Saludos.