Ir al contenido



Foto

Descrifrar en Android AES256

Android; AES256 Descifrar

  • Por favor identifícate para responder
25 respuestas en este tema

#1 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.475 mensajes
  • LocationMexico City

Escrito 04 abril 2016 - 08:07

Buenas noches a todos amigos, ando aquí con una gran duda para poder descifrar una cadena en Android.

 

Les cuento. Tengo una cadena que cifro mediante el código para cifrar con AES256 que Seoane nos compartió y que funciona en una aplicación Delphi sin problemas. Ahora requiero descifrar esa misma cadena pero en Android. El método que descifra en Delphi funciona perfecto pero en Android me marca un error: Out of Memory.


delphi
  1. function Convierte(Str,Clave: String): String;
  2. var
  3. Src: TMemoryStream;
  4. Dst: TStringStream;
  5. Size: Integer;
  6. Key: TAESKey;
  7. ExpandedKey: TAESExpandedKey;
  8. begin
  9. Result:= EmptyStr;
  10. Src:= TMemoryStream.Create;
  11. try
  12. Dst:= TStringStream.Create(Str);
  13. try
  14. StrToStream(Str,Src);
  15. Src.Position:= 0;
  16. FillChar(Key,Sizeof(Key),#0);
  17. if Length(Clave) > Sizeof(Key) then
  18. move(PChar(Clave)^,Key,Sizeof(key))
  19. else
  20. move(PChar(Clave)^,Key,Length(Clave));
  21. AESExpandKey(ExpandedKey,Key);
  22. // Leemos el tamaño del texto
  23. Src.ReadBuffer(Size,Sizeof(Size));
  24. ConvierteStreamECB(Src,Dst,ExpandedKey);
  25. Dst.Size:= Size; // AQUI DA EL ERROR DE OUT OF MEMORY
  26. Result:= Dst.DataString;
  27. finally
  28. Dst.Free;
  29. end;
  30. finally
  31. Src.Free;
  32. end;
  33. end;

Sigo investigando... alguna idea ?

 

Saludox ! :)


  • 0

#2 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 623 mensajes
  • LocationArgentina

Escrito 04 abril 2016 - 08:44

Fenareth

 

Hay que tener muy en cuenta que en los compiladores mobile (iOs y Android, y ahora no recuerdo si para OS X tambien aplica)

 

Los string son de indice 0-based

 

En el "Delphi tradicional" para Win32 y Win64, los string son de indice 1-based

 

Ademas, Windows agrega un nulo al final de todas las cadenas

 

Todo esto hace que el codigo que trabaja a bajo nivel, con streams, punteros y buffers de memoria haya que "revisarlo un poco"

 

No soy un experto en bajo nivel, pero tiene toda la pinta de que hay un desborde de memoria por alli

 

Revisa este enlace


  • 1

#3 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.475 mensajes
  • LocationMexico City

Escrito 06 abril 2016 - 12:32

Amigo Agustin muchas gracias por la ayuda, revisaré lo que comentas y les retroalimento...

 

Saludox ! :)


  • 0

#4 seoane

seoane

    Advanced Member

  • Administrador
  • 1.214 mensajes
  • LocationEspaña

Escrito 06 abril 2016 - 06:10

Hola Fenareth, cuanto tiempo sin pasarme por aqui ...

 

Vamos al tema que nos ocupa. El problema esta aqui:


delphi
  1. Src.ReadBuffer(Size,Sizeof(Size));

Cuando se lee el tamaño original de la cadena.

 

El problema es que la forma de representar un integer en un PC y en un telefono es diferente, debido a que utilizan diferentes tipos de CPU. En la wikipedia lo explican con mas detalle: https://es.wikipedia...wiki/Endianness

 

 Para solucionarlo vamos a tener que leer el tamaño de una forma un poco mas rudimentaria pero independiente de la arquitectura que estemos usando:


delphi
  1. // Declaramos esta funcion
  2. function ReadInteger(Stream: TStream): Integer;
  3. var
  4. P: array[0..3] of byte;
  5. i: Integer;
  6. begin
  7. Stream.ReadBuffer(P,4);
  8. Result:= P[3];
  9. for i:= 2 downto 0 do
  10. begin
  11. Result:= Result * $100;
  12. Result:= Result + P[i];
  13. end;
  14. end;
  15.  
  16. // Y cambiamos la linea problematica por esta otra
  17. Size:= ReadInteger(Stream);

Con esto solucionamos el problema. Y si queremos dejarlo ya todo bien atado, y que el telefono cifre bien, en la funcion de cifrado debemos de usar esto para guardar el tamaño:


delphi
  1. procedure WriteInteger(Stream: TStream; value: Integer);
  2. var
  3. B: Byte;
  4. i: Integer;
  5. begin
  6. for i:= 1 to 4 do
  7. begin
  8. B:= value mod $100;
  9. Stream.WriteBuffer(B,1);
  10. value:= value div $100;
  11. end;
  12. end;

Aunque si en el telefono solo vas a descifrar podemos saltarnos esta parte.

 

Saludos


  • 2

#5 seoane

seoane

    Advanced Member

  • Administrador
  • 1.214 mensajes
  • LocationEspaña

Escrito 06 abril 2016 - 06:13

Se me olvidaba. Si puedes usa mejor el tipo AnsiString en vez de String.


  • 1

#6 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.475 mensajes
  • LocationMexico City

Escrito 08 abril 2016 - 07:59

Hola amigo Seoane muchas gracias por tu ayuda, el día de ayer estuve implementando el cambio sugerido pero el error de Out Of Memory sigue ocurriendo en la misma línea donde sucedía en un principio. Te muestro el cambio como quedó:

delphi
  1. function ReadInteger(Stream: TStream): Integer; //NUEVA FUNCIÓN INTEGRADA
  2. var
  3. P: array[0..3] of byte;
  4. i: Integer;
  5. begin
  6. Stream.ReadBuffer(P,4);
  7. Result:= P[3];
  8. for i:= 2 downto 0 do
  9. begin
  10. Result:= Result * $100;
  11. Result:= Result + P[i];
  12. end;
  13. end;
  14.  
  15. function Convierte(Str,Clave: String): String;
  16. var
  17. Src: TMemoryStream;
  18. Dst: TStringStream;
  19. Size: Integer;
  20. Key: TAESKey;
  21. ExpandedKey: TAESExpandedKey;
  22. begin
  23. Result:= EmptyStr;
  24. Src:= TMemoryStream.Create;
  25. try
  26. Dst:= TStringStream.Create(Str);
  27. try
  28. StrToStream(Str,Src);
  29. Src.Position:= 0;
  30. FillChar(Key,Sizeof(Key),#0);
  31. if Length(Clave) > Sizeof(Key) then
  32. move(PChar(Clave)^,Key,Sizeof(key))
  33. else
  34. move(PChar(Clave)^,Key,Length(Clave));
  35. AESExpandKey(ExpandedKey,Key);
  36. // Leemos el tamaño del texto
  37. Size:= ReadInteger(Src); // CAMBIO DE LÍNEA POR NUEVA FUNCIÓN
  38. ConvierteStreamECB(Src,Dst,ExpandedKey);
  39. Dst.Size:= Size; // ERROR DE OUT OF MEMORY
  40. Result:= Dst.DataString;
  41. finally
  42. Dst.Free;
  43. end;
  44. finally
  45. Src.Free;
  46. end;
  47. end;
  48.  

Estoy viendo lo de tu sugerencia de cambiar los String por AnsiString y ver si por ahí pudiera ser el problema :(
 
Gracias de nuevo y ojalá tengas oportunidad de seguir echándome la mano (y)
 
Saludox ! :)
  • 0

#7 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.475 mensajes
  • LocationMexico City

Escrito 08 abril 2016 - 08:48

He hecho el cambio por AnsiString y tampoco lo he logrado.

 

Dando vueltas por las funciones que se ejecutan al momento de asignarle el size al TStringStream que es donde me salta el error, veo que ingresa a esta función:


delphi
  1. function _ReallocMem(var P: Pointer; NewSize: NativeInt): Pointer;
  2. {$IFDEF PUREPASCAL}
  3. begin
  4. if P <> nil then
  5. begin
  6. if NewSize > 0 then
  7. begin
  8. Result := MemoryManager.ReallocMem(P, NewSize); // AQUÍ INGRESA Y REGRESA NIL
  9. if Result = nil then
  10. Error(reOutOfMemory); // CON NIL MANDA EL ERROR DE OUT OF MEMORY
  11. end
  12. else
  13. begin
  14. if MemoryManager.FreeMem(P) <> 0 then
  15. Error(reInvalidPtr);
  16. Result := nil;
  17. end;
  18. P := Result;
  19. end else
  20. begin
  21. if NewSize <= 0 then
  22. Exit(nil);
  23. Result := MemoryManager.GetMem(NewSize);
  24. if Result = nil then
  25. Error(reOutOfMemory);
  26. P := Result;
  27. end;
  28. end;
  29. {$ELSE !PUREPASCAL}

Al regresar NIL la función de asignación de "reubicación" ? manda el mentado Out of Memory  :(

 

Sigo buscando solución :

 

Saludox ! :)


  • 0

#8 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.825 mensajes
  • LocationArgentina

Escrito 09 abril 2016 - 07:21

Fíjate si puedes entrear a ReallocMem() del MemoryManager y ver que hace. Prueba también examinando el valor de las variables.

El problema del endianness surge cuando se va a estar intercambiando archivos entre dispositivos de distintos endianness. Si se va a cifrar y descrifrar únicamente con Android no hace falta hacer un SwapEndian como sugiere Domingo.

 

Ahora bien, si efectivamente dicho archivo cifrado se va a estar intercambiando entre una PC y un Android las cosas si deben cuidarse. La enorme mayoría de las PCs son LittleEndian mientras que los celulares, tablet y la enorme mayoría de los ARM en general son BigEndian.

El truco está en guardar todo en un Endian prefijado: o todo se guarda en BigEndian o todo se guarda en LitteEndian, es decir tomamos el dato entero del tipo nativo que tiene el equipo y procedemos a guardado en BigEndian o en LittleEndian. Luego al momento de leer se procede a efectuar el paso de BigEndian al nativo o bien LittleEndian al nativo según cual criterio se ha adoptado.

 

Lazarus al menos cuenta ya con funciones que hacen esto:

BEToN(): BigEndian to Native

LEToN(): LittleEndian to Native

NToBE(): Native to BigEndian

NToLE(): Native to LittleEndian

 

La magia del compilador hace el trabajo solo. Gracias a esas funciones, es que el se procede a intercambiar los bytes solamente cuando es absolutamente necesario.

El código debería andar en Android como también lo debiera de hacer bajo una PC. Cuando uno hace:

 

MiVariable := 123456789;

 

Ya sea en LittleEndian o en BigEndian el compilador internamente guarda eso en su estado Nativo. Por tanto mientras esté en su mismo "entorno" las cosas debieran de funcionar.

 

Si tu fuerzas el código a invertir los bytes para la variable Size y luego intentas reservar memoria con ese tamaño, obviamente lo que hay en esa variable ya no es el valor esperado ¡Es cualquier otra cosa! Y eso va a suceder tanto en un BigEndian como en un LittleEndian.

 

¿Cuál es el verdadero error? La verdad lo desconozco. No he compilado ni desarrollado nada para Android, y las cosas en Delphi han cambiado mucho comparado con el D6 que yo solía usar. Sólo quiero ilustrar esa pequeña falla en el tema del endianness.

 

Aquí yo estuve deliberando un poco sobre el tema para que te hagas una idea.

 

Saludos,


  • 1

#9 seoane

seoane

    Advanced Member

  • Administrador
  • 1.214 mensajes
  • LocationEspaña

Escrito 10 abril 2016 - 04:12

Lo que necesitamos saber es que valor toma la variable "Size". 

 

Sospecho que el problema esta en que tiene un valor muy alto, y cuando se intenta reservar esa memoria da el error de "out of memory".

 

¿Podrias cifrar un texto cualquiera y ponerlo aqui para que le eche un vistazo?

 

Siento no poder ayudarte mas, pero no tengo una version de delphi que compile para android :(


  • 0

#10 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.475 mensajes
  • LocationMexico City

Escrito 10 abril 2016 - 06:39

Hola amigo Seoane

 

Fíjate que desde el principio algunas de mis sospechas fue el tamaño de la memoria que se intentaba asignar. Revisando las características del dispositivo donde estaba haciendo pruebas puedo ver que tiene 3 GB de memoria RAM lo que no me parece que sea poco, pero no sé si estén siendo insuficientes.

 

El valor que toma Size lo venía ya monitoreando desde el inicio y es de 939524096 ¿bytes?. De ser así, estaría intentando reservar una memoria de casi 1 GB (0.875 para ser más exactos).

 

La cadena ya cifrada que intento recuperar es: UAAAAOPJ/T7n9CG6Dd1Jnzifw7IRl/6niVgWlq74U3PnIDUWErbL5RLw30H8PzQ+y+ZA2hHZH9DtRy1yrMYdaSTqCDPrFSJL7FGlNXTqUya0XKEK. Con la aplicación de Delphi me da el resultado esperado, con Android pues bueno, estamos atorados con el famoso Out of Memory...

 

Te agradezco el tiempo que te tomas para responder amigo, así como el de todos los que han participado hasta ahora, aún seguimos aprendiendo mucho de compilaciones hacia Android, ésto lo podremos solucionar de alguna manera u otra... 

 

Gracias a todos de nuevo (y)

 

Saludox ! :)


  • 0

#11 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.475 mensajes
  • LocationMexico City

Escrito 10 abril 2016 - 06:53

Se me ocurrió hacer una prueba asignando manualmente la mitad de Size y ver cómo se comportaba el descifrado. Les comento los resultados:

 

La asignación al TStringStream fue exitosa (sin el error del Out of Memory) pero al momento de enviar el DataString del TStringMemory como resultado de la función, me arroja otro error que dice: No mapping por the Unicode character exists in the target multy-byte code page. Haciendo un "break" en la aplicación al momento del error me envía a la función TEncoding.GetString de la unidad System.SysUtils. ¿Será resultado de la asignación manual de la mitad de memoria reservada?

 

En fin, seguimos con las pruebas  8o|

 

Saludox ! :)


  • 0

#12 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.825 mensajes
  • LocationArgentina

Escrito 11 abril 2016 - 06:06

Hola Fena, no creo que este segundo error sea por haber hecho la asignación manual. Son dos errores independientes y no creo que tengan relación entre si.

 

Pregunto: ¿Esa cadena cifrada, fue hecha desde una PC? Si es así entonces el código debe ser endianness-friendly puesto que como dije: Si se va a estar llevando archivos entre PCs y Móviles se debe tener en cuenta el endianness tanto al momento de guardar como al de leer.

¿Porqué? Porque si en la cadena está almacenado un valor entero debe leerse y guardarse desde un tipo de endian específico y llevarse al nativo. Lo más lógico es que si se hizo desde una PC es que dicho valor esté guardado en formato little-endian. Ahora cuando este mismo archivo se lee desde un móvil deberá hacerse un LEToN() para tomar ese valor LittleEndian para llevarse al Nativo (BigEndian). Ahora bien si desde el mismo móvil se van a hacer cambios y rehusar el archivo, por cuestiones de compatibilidad deberá aplicarse un NToLE() al momento de guardar el tamaño.

En este ejemplo se consideró que el archivo siempre estará en LittleEndian, puede hacerse con el BigEndian si se desea. Lo importante es que se mantenga siempre esto. Porque si uno genera un archivo en LittleEndian y luego procede a leer y/o sobreguardar con un BigEndian se pierde todo y la cosa truena.

 

El otro problema parece apuntar a una cuestión de encoding. A mi me da entender que se está guardando en un formato y al momento de leer se espera otro. No estoy seguro pero creo que en móviles el encoding por defecto es UTF-8 mientras que en Windows el sistema por defecto es el de WIN1252 en la mayoría de los equipos. WIN1252 es un subconjunto de la ISO 8859-1. En los caracteres imprimibles tiene el mismo formato de bits, pero en los no imprimibles difiere. Y que yo sepa Delphi ya es UTF-16.

Prueba ver esto, quizá esté ahí el problema. Aunque no estoy completamente seguro. El texto del error dice algo sobre el tamaño de página de código... como si se hubiera guardado/leído en formatos de diferentes tamaños de bytes... Tanto UTF-8 como WIN1552 son de 2 bytes... ¿Será que al guardar se usa un formato de 1 byte? ¿O al leer? Si es que Delphi ya es UTF-16 puedo entender entonces que ahora los bytes sean 4.

Deberás verificar esto.

En Lazarus al menos se asume UTF-8 por defecto, y tiene funciones para convertir entre diferentes formatos. Yo ya estuve aprendiendo algunas lecciones sobre el tema, aquí y aquí.

 

Saludos,


  • 1

#13 seoane

seoane

    Advanced Member

  • Administrador
  • 1.214 mensajes
  • LocationEspaña

Escrito 11 abril 2016 - 10:12

No mw pusiste la clave para descifrar el ejemplo ;)


  • 0

#14 seoane

seoane

    Advanced Member

  • Administrador
  • 1.214 mensajes
  • LocationEspaña

Escrito 11 abril 2016 - 10:27

Acabo de hacer una pequeña prueba con freepascal.

 

Compilando el mismo programa en lazarus 32bits en el PC y en freepascal para android.

 

El programa de ejemplo  es (un refrito de mi unit SeEasyAES.pas)


delphi
  1. program test01;
  2.  
  3. {$IFDEF FPC}
  4. {$MODE delphi}
  5. {$ENDIF}
  6. {$APPTYPE CONSOLE}
  7.  
  8. uses
  9. SysUtils,
  10. Classes,
  11. SeAES256,
  12. SeBase64,
  13. SeMD5,
  14. SeStreams,
  15. SeSHA256;
  16.  
  17. type
  18. // Cabecera que anteponemos a los datos cifrados
  19. TEasyAESHeader = packed record
  20. OriginalDataSize: Integer;
  21. end;
  22.  
  23. procedure EasyGenKey(var Key: TAESKey; Password: AnsiString);
  24. var
  25. Temp: TMemoryStream;
  26. begin
  27. FillChar(Key,Sizeof(Key),#0);
  28. if Length(Password) > Sizeof(Key) then
  29. move(PChar(Password)^,Key,Sizeof(key))
  30. else
  31. move(PChar(Password)^,Key,Length(Password));
  32. end;
  33.  
  34. procedure EasyAESEnc(Src, Dst: TStream; Password: AnsiString); overload;
  35. var
  36. Header: TEasyAESHeader;
  37. AESKey: TAESKey;
  38. AESEnc: TAESEnc;
  39. begin
  40. // Inicializamos la cebecera
  41. FillChar(Header,Sizeof(Header),0);
  42. with Header do
  43. begin
  44. OriginalDataSize:= Src.Size;
  45. end;
  46. // Escribimos la cabecera
  47. Dst.WriteBuffer(Header,Sizeof(Header));
  48. // Generamos la clave
  49. EasyGenKey(AESKey,Password);
  50. AESEnc:= TAESEnc.Create(Dst,AESKey);
  51. try
  52. // Ciframos el stream
  53. AESEnc.CopyFrom(Src,Src.Size);
  54. finally
  55. AESEnc.Free;
  56. end;
  57. end;
  58.  
  59. procedure EasyAESDec(Src, Dst: TStream; Password: AnsiString); overload;
  60. var
  61. Header: TEasyAESHeader;
  62. AESKey: TAESKey;
  63. AESDec: TAESDec;
  64. begin
  65. Src.Position:= 0;
  66. // Leemos la cabecera
  67. Src.ReadBuffer(Header,Sizeof(Header));
  68. // Generamos la clave
  69. EasyGenKey(AESKey,Password);
  70. AESDec:= TAESDec.Create(Dst,AESKey);
  71. try
  72. // Desciframos el stream
  73. AESDec.CopyFrom(Src,Src.Size - Sizeof(Header));
  74. // Restauramos su tamaño original
  75. if (Header.OriginalDataSize <= Dst.Size) then
  76. Dst.Size:= Header.OriginalDataSize
  77. else
  78. raise Exception.Create('Invalid data size');
  79. finally
  80. AESDec.Free;
  81. end;
  82. end;
  83.  
  84. function EasyAESEnc(Str, Password: AnsiString): AnsiString; overload;
  85. var
  86. Src, Dst: TMemoryStream;
  87. begin
  88. Src:= TMemoryStream.Create;
  89. Dst:= TMemoryStream.Create;
  90. try
  91. // Guardamos el texto a cifrar en un stream temporal
  92. Src.WriteBuffer(PAnsiChar(Str)^,Length(Str)*SizeOf(AnsiChar));
  93. Src.Position:= 0;
  94. // Ciframos el stream
  95. EasyAESEnc(Src,Dst,Password);
  96. // Codificamos el resultado en base64
  97. Result:= BinToStr(PByteArray(Dst.Memory),Dst.Size);
  98. finally
  99. Src.Free;
  100. Dst.Free;
  101. end;
  102. end;
  103.  
  104. function EasyAESDec(Str, Password: AnsiString): AnsiString; overload;
  105. var
  106. Src, Dst: TMemoryStream;
  107. begin
  108. Src:= TMemoryStream.Create;
  109. Dst:= TMemoryStream.Create;
  110. try
  111. // Metemos los datos cifrados en un stream: base64 -> binario
  112. StrToStream(Str,Src);
  113. Src.Position:= 0;
  114. // Desciframos el stream
  115. EasyAESDec(Src,Dst,Password);
  116. // Devolvemos el texto descifrado
  117. Result:= Copy(AnsiString(PAnsiChar(Dst.Memory)),1,Dst.Size div Sizeof(AnsiChar));
  118. finally
  119. Src.Free;
  120. Dst.Free;
  121. end;
  122. end;
  123.  
  124. procedure EasyAESEnc(SrcFile, DstFile, Password: AnsiString); overload;
  125. var
  126. Src, Dst: TFileStream;
  127. begin
  128. Src:= TFileStream.Create(SrcFile,fmOpenRead or fmShareDenyWrite);
  129. try
  130. Dst:= TFileStream.Create(DstFile,fmCreate);
  131. try
  132. EasyAESEnc(Src,Dst,Password);
  133. finally
  134. Dst.Free;
  135. end;
  136. finally
  137. Src.Free;
  138. end;
  139. end;
  140.  
  141. procedure EasyAESDec(SrcFile, DstFile, Password: AnsiString); overload;
  142. var
  143. Src, Dst: TFileStream;
  144. begin
  145. Src:= TFileStream.Create(SrcFile,fmOpenRead or fmShareDenyWrite);
  146. try
  147. Dst:= TFileStream.Create(DstFile,fmCreate);
  148. try
  149. EasyAESDec(Src,Dst,Password);
  150. finally
  151. Dst.Free;
  152. end;
  153. finally
  154. Src.Free;
  155. end;
  156. end;
  157.  
  158.  
  159. Var
  160. Ejemplo: AnsiString;
  161. begin
  162. Ejemplo:= 'Hola mundo';
  163. Writeln(Ejemplo);
  164. Ejemplo:= EasyAESEnc(Ejemplo,'Password');
  165. Writeln(Ejemplo);
  166. Ejemplo:= EasyAESDec(Ejemplo,'Password');
  167. Writeln(Ejemplo);
  168. readln;
  169. end.

El resultado lo puedes ver en la imagen adjunta

 

Archivos adjuntos


  • 0

#15 seoane

seoane

    Advanced Member

  • Administrador
  • 1.214 mensajes
  • LocationEspaña

Escrito 11 abril 2016 - 10:30

La pregunta es si tienes que guardar compatibilidad con alguna otra aplicacion antigua, o podemos buscar un formato mejor para guardar el texto comprimido. Un formato en el que no tengamos problemas con el orden de los bytes o el tamao de los caracteres.

 

Porque la unidad easyAES que se encuentra en la ultima version se podria adaptar facilmente, solo tendriamos que corregir unos detalles.


  • 0

#16 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.475 mensajes
  • LocationMexico City

Escrito 11 abril 2016 - 10:48

Amigos ya los puse a trabajar y a investigar, lo agradezco mucho...

 

 

No mw pusiste la clave para descifrar el ejemplo ;)

 

A poco era necesario ???  *-)  *-)  *-)  :D  :D  :D  :D

 

:embarrassed:

 

Llegando a casa pruebo con el código que acabas de sugerir y les comento el resultado ( ojalá sea satisfactorio (y) )...

 

 

La pregunta es si tienes que guardar compatibilidad con alguna otra aplicacion antigua, o podemos buscar un formato mejor para guardar el texto comprimido. Un formato en el que no tengamos problemas con el orden de los bytes o el tamao de los caracteres.

 

Porque la unidad easyAES que se encuentra en la ultima version se podria adaptar facilmente, solo tendriamos que corregir unos detalles.

 

Tengo una aplicación Delphi que es la que genera el cifrado que ahora intento descifrar, de ser necesario la cambiaré pero no por ahora, tal vez en unos 6 meses que es cuando podré generar de nuevo los códigos cifrados que ahora pretendo leer.

 

Por el momento si estoy atada a ese código de cifrado/descifrado (ves amigo Delphius ?, me estoy portando bien, jejeje) pero como te comento amigo Seoane, tengo la posibilidad de cambiar todo pero hasta dentro de unos 4 - 6 meses.

 

Les agradezco bastante la ayuda...

 

Saludox ! :) 


  • 0

#17 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.825 mensajes
  • LocationArgentina

Escrito 11 abril 2016 - 11:13

Domingo, no he probado tu último código, y ni he compilado nunca para Android... Me asalta una duda. ¿Compilaste para cada uno por separado? ¿Es decir, hiciste un stream con la PC por un lado y otro con la app Android? Porque si es así, obviamente que resulta la cosa... cada uno trabaja con lo "suyo". El asunto se va a poner un poco más liado cuando tenga que guardar el contenido cifrado y recuperarlo en y desde diferentes dispositivos.

Prueba guardando el contenido cifrado ya sea desde la applicación PC o la móvil y en llevarlo y leerlo con la aplicación "opuesta". A ver que resulta.

Yo también he llegado a pensar que el conflicto con el Size en Android tuviera que ver con el gran tamaño y que quizá sea que es demasiado para la RAM y/o el espacio disponible en la SD (si es que hay una disponible). Suena como lo más probable.

 

Gaby, yo que vos no esperaría a que llegue ese día y me adelantaría en hacerlo lo más multiplataforma posible. ¡Quien sabe que te espera para ese entonces! Es preferible que prepares la cancha ahora que ya estás en el estadio y calentando... No vaya a ser cosa que al ponerte en el banco y llegue ese día te encuentre con el músculo en frio.

El trabajo justamente implica luchar contra el endianness y apoyo la idea de Domingo en considerar usar algún formato de codificación concreto para que al momento de descifrar proceder a hacer el paso inverso adecuado para la multiplataforma y no tener que lidiar con posibles conflictos de encoding. Algo como usar Base64 y/o UTF8 y hacer UTF8ToSys()/SysToUTF8() que dispone Lazarus (creería que Delphi tiene algo equivalente a estas funciones).

 

EDITO:

Estoy tratando de informarme sobre como se puede detectar que endianness se está empleando. Lazarus cuenta con directiva de compilación para cada uno, lo que hace muy fácil la tarea. No encuentro las mismas o algo parecido en Delphi, y me cuesta creer que no cuente con algo de endianness-friendly.

Voy a tratar de investigar algo más sobre el error encoding, a ver si encuentro por donde más se puede hilar.

 

Saludos,


  • 0

#18 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.825 mensajes
  • LocationArgentina

Escrito 11 abril 2016 - 11:49

La búsqueda rápida sobre No mapping por the Unicode character exists in the target multy-byte code page delphi me ha llevado a resultados como los siguientes:

Link 1

Link 2

Link 3

 

Y hay más. Pareciera apuntar justo a algo que yo estaba comentando. Debes definir desde un principio que encoding usar. En esos enlaces sugieren que al crear el stream se le indique que usen UTF-8. De modo que tanto para el cifrado como descifrado se esté en acuerdo a trabajar con dicho formato.

Puedes ir probando este punto.

 

Saludos,


  • 1

#19 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 623 mensajes
  • LocationArgentina

Escrito 11 abril 2016 - 01:59

Y hay más. Pareciera apuntar justo a algo que yo estaba comentando. Debes definir desde un principio que encoding usar. En esos enlaces sugieren que al crear el stream se le indique que usen UTF-8. De modo que tanto para el cifrado como descifrado se esté en acuerdo a trabajar con dicho formato.

 

 

Totalmente cierto

 

El tipo "string" dejo de existir. No tenes mas un string; tenes un arreglo de bytes. Agarra el arreglo de bytes, y usa un determinado Encoding, y recien ahi tenes el "texto"


  • 0

#20 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.825 mensajes
  • LocationArgentina

Escrito 11 abril 2016 - 02:12

Totalmente cierto

 

El tipo "string" dejo de existir. No tenes mas un string; tenes un arreglo de bytes. Agarra el arreglo de bytes, y usa un determinado Encoding, y recien ahi tenes el "texto"

 

Visto así, la verdad es que tiene mucho sentido y hasta parece lo más razonable considerando la cantidad de encodings que hay.

 

Hasta se podría encarar el diseño con una clase abstracta TEncoding y derivar de ésta para que éstas se encarguen de interpretar el array de bytes como corresponde.

Estas clases harían todo el trabajo sucio y ya nunca más un tipo string. Necesitas trabajar con UTF-8, tienes la clase UTF-8 y pum... Necesitas Unicode, la clase Unicode. Mierda... peguenme... ¡Acabo de pensar como un Java Boy! :|

 

Saludos,


  • 0