Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 01-06-2014
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.110
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Problemas al tratar de guardar y después recuperar una cadena de texto cifrada

Hola a todos,

A ver si alguien puede echarme una mano con cierto problema que me he topado. Resulta que en uno de mis programas doy a los usuarios la posibilidad de cifrar y descrifrar cadenas y archivos. Tanto para cifrar y descifrar cadenas como archivos utilizo la misma clase, el mismo código, sin embargo, algo falla a la hora de cifrar cadenas.

Y aquí empieza el problema. En realidad el cifrado de cadenas no falla... pero, este programa que digo, se supone que tiene que retornar al usuario la cadena cifrada, es decir, para poder descifrarla después. Ahora bien, aunque estoy funciona... cómo decirlo... "en memoria", no funciona si se guarda la cadena cifrada en algún lugar.

¿Qué quiere decir algún lugar? Pues, por ejemplo, si ciframos una cadena y queremos mostrar la cadena cifrada en un "MessageBox", lo que este muestra es sólo una parte de dicha cadena cifrada, es como si se "perdiese" parte de la cadena, de manera que luego, claro está, es imposible descifrar dicha cadena y obtener el texto original.

Lo mismo ocurre si en lugar de mostrar la cadena en un "MessageBox" pretendemos copiarla en el portapapeles de Windows, mostrarla en un "TMemo", etc.: Lo que obtenemos es sólo una parte de la cadena cifrada, de manera que después lógicamente no hay forma de descifrarla. Ahora bien, si no mostramos o guardamos dicha cadena cifrada, entonces todo funciona como se espera.

Voy a tratar de explicarlo con un poco de código:

Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
const
  SOURCE_STR = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
var
  cipher : TCipher;
  originalText, encryptedText, decryptedText : string;
begin
  originalText := DupeString(SOURCE_STR, 100) + ' #####';

  cipher := TCipher.Create();
  try
    encryptedText := cipher.EncryptString(originalText, 'password', haSHA512);

    decryptedText := cipher.DecryptString(encryptedText, 'password', haSHA512);

    ShowMessage(decryptedText);
  finally
    cipher.Free();
  end;
end;

Al ejecutarse el código anterior, el "ShowMessage" del final nos mostrará lo que esperamos: el texto original. Es decir, en el código anterior hemos cifrado una cadena, hemos descifrado la cadena previamente cifrada, y, mostrando esta última en el "ShowMessage" obtenemos el resultado esperado: una copia exacta de la cadena original.

¿Dónde está el problema entonces? El problema reside en que, como he dicho, de lo que se trata es de devolver la cadena cifrada al usuario, para que, digamos, el la guarde donde quiera, de manera que luego pueda descifrarla y obtener su cadena original. Pero esto no funciona.

De nuevo un poco de código:

Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
const
  SOURCE_STR = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
var
  cipher : TCipher;
  originalText, encryptedText, decryptedText : string;
begin
  originalText := DupeString(SOURCE_STR, 100) + ' #####';

  cipher := TCipher.Create();
  try
    encryptedText := cipher.EncryptString(originalText, 'password', haSHA512);

    ShowMessage(encryptedText);

    decryptedText := cipher.DecryptString(encryptedText, 'password', haSHA512);

    ShowMessage(decryptedText);
  finally
    cipher.Free();
  end;
end;

El anterior código añade, justo después de cifrar la cadena, un nuevo "ShowMessage". Se supone que este "ShowMessage" debería mostrar la cadena cifrada, pero, no lo hace, es decir, lo que muestra es sólo parte de la cadena. Para que se entienda un poco mejor (o para intentarlo por mi parte, al menos) veamos el último trozo de código:

Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
const
  SOURCE_STR = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
var
  cipher : TCipher;
  originalText, encryptedText, decryptedText : string;
begin
  originalText := DupeString(SOURCE_STR, 100) + ' #####';

  cipher := TCipher.Create();
  try
    encryptedText := cipher.EncryptString(originalText, 'password', haSHA512);

    Memo1.Text := encryptedText;

    decryptedText := cipher.DecryptString(Memo1.Text, 'password', haSHA512);

    ShowMessage(decryptedText);
  finally
    cipher.Free();
  end;
end;

En este último caso, en lugar de mostrar mediante un "ShowMessage" la cadena cifrada, la guardamos en un "TMemo". Así que después, tratamos de descifrar la cadena que acabamos de guardar en dicho "TMemo", sin embargo, no obtendremos el resultado deseado, puesto que el "TMemo" sólo contendrá/mostrará parte de la cadena cifrada, y, por tanto, será imposible obtener la original a partir de ella.

Estoy utilizando la cierta API de Windows que permite cifrar y descifrar archivos, todo ello encapsulado en una clase que ya publiqué hace tiempo aquí, basada en código del maestro Seoane. La adjunto en este hilo por si alguien quiere comprobar lo dicho. El caso es que dicha clase parece funcionar correctamente, puesto que, como se puede apreciar en el primer bloque de codigo mostrado, el cifrado y descifrado, tanto de cadenas como de archivos, se lleva a cabo perfectamente.

Pero claro, cuando ciframos y desciframos una cadena no mostramos la cadena cifrada, ni tampoco la guardamos en ningún otro lugar que no sea la variable correspondiente. Hecho esto así, como puede verse, todo funciona como se espera. Sin embargo, al tratar de guardar la cadena cifrada, para después y a partir de ella recuperar la cadena original parece tarea imposible.

¿Tendrá que ver con los caracteres, ciertamente "raros", que contiene una cadena cifrada? He probado a codificar esta cadena cifrada en "base 64", pero, tampoco he obtenido los resultados esperados. ¿A alguien se le ocurre alguna posible solución? ¿Alguien con experiencia en estos menesteres que sepa decirme cómo demonios salir de este lío en el que estoy metido?

Si ya has llegado leyendo hasta aquí, muchas gracias de antemano por tu posible ayuda.
Archivos Adjuntos
Tipo de Archivo: zip UCipher.zip (2,4 KB, 7 visitas)
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #2  
Antiguo 01-06-2014
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.062
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
CREO que es porque obtienes caracteres inferiores al código 32 ascii y se pierden, por ejemplo el 7 haría un "beep" y se perdería, el cero corta la cadena por donde esté, etc.
Yo lo que hago, no sé si para bien o mal, pero funciona, es convertirlas a code64, así puedo mostrarla en cualquier mensaje, memo, etc.
Responder Con Cita
  #3  
Antiguo 01-06-2014
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.110
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Gracias Casimiro. Que se "pierden" caracteres es evidente... aunque, ojo, sólo a la hora de guardar (o mostrarla en un "MessageBox", un "TMemo", etc.) la cadena cifrada: puesto que usando la variable que la contiene nosotros podemos descifrarla sin problemas. Ahora bien, he probado a convertir la cadena a "base 64" y el problema parece persistir. ¿Por qué digo parece? Porque he estado tan liado con esto que ahora mismo no sé si hice bien la prueba con "base 64". Mañana lo intentaré de nuevo. Sin embargo ahora mismo juraría que no es solución: que dichos caracteres se pierden también al tratar de convertir la cadena cifrada a "base 64", es decir, "faltan" cuando se decodifica la cadena (desde "base 64") y trata uno de descifrarla.

De todas formas, tal vez exista algún otro tipo de codificación posible en lugar de "base 64". Me explico. El debugger de Delphi me muestra el contenido de la cadena cifrada, pero, no reconozco dicho contenido como el que se guarda al cifrar un archivo (usando la misma clase) o una cadena, es decir, ¿podría Delphi estar codificando dicha cadena para mostrarla en el debugger? ¿Y qué codificación usaría? Ahora bien, esto tal vez no sirva de nada... pues seguramente Delphi no usará el contenido de la cadena que me muestra a mí en el debugger... sino que usará la propia variable que contenga la cadena cifrada. Espero que se entienda lo que quiero decir.

Pero sí... tal vez se trata de codificar dicha cadena cifrada de forma que no se pierdan los caracteres...

Gracias de nuevo Casimiro. Se agradece cualquier tipo de ayuda con este asunto, porque, en efecto, tengo que "presentar" alguna solución.
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 01-06-2014 a las 23:04:25.
Responder Con Cita
  #4  
Antiguo 01-06-2014
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.110
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola de nuevo,

Curiosamente, aquí se describe exactamente (si no me equivoco) el problema que tengo. Y la solución propuesta pasa por codificar en "base 64" la cadena cifrada... ¿lo habré hecho yo entonces mal en mis anteriores pruebas? Mañana volveré a comprobarlo y veremos. Por favor recordad que cualquier tipo de ayuda sigue siendo bienvenida.
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 01-06-2014 a las 23:52:27.
Responder Con Cita
  #5  
Antiguo 02-06-2014
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.110
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Tal vez esta tarde he metido la pata al probar codificando la cadena cifrada en "base 64": he probado de nuevo y he podido comprobar que, en efecto, codificar la cadena cifrada tal vez sea una solución. No sé si lo será para mi problema en concreto, puesto que no puedo probarlo todavía en el programa en cuestión, pero, en un programa de prueba que estoy haciendo aquí, en efecto, algo así funciona como se espera:

Código Delphi [-]
uses
  StrUtils, IdCoderMIME, UCipher;

function Encode(str : string) : string;
var
  encoder : TIdEncoderMIME;
begin
  encoder := TIdEncoderMIME.Create();
  try
    result := encoder.Encode(str);
  finally
    encoder.Free();
  end;
end;

function Decode(str : string) : string;
var
  decoder : TIdDecoderMIME;
begin
  decoder := TIdDecoderMIME.Create();
  try
    result := decoder.DecodeString(str);
  finally
    decoder.Free();
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
const
  SAMPLE_TEXT = 'Hello dolly how are you I am fine ok goodbye. ';
var
  cipher : TCipher;
  encryptedText : string;
begin
  cipher := TCipher.Create();
  try
    encryptedText := cipher.EncryptString(DupeString(SAMPLE_TEXT, 150), 'password', haSHA512);

    Memo1.Text := Encode(encryptedText);

    ShowMessage(cipher.DecryptString(Decode(Memo1.Text), 'password', haSHA512));
  finally
    cipher.Free();
  end;
end;

Como puede verse estamos guardando la cadena cifrada en el "TMemo", no obstante, lo hacemos codificándola en "base 64". Pues bien, después de descodificarla de nuevo podemos descifrarla obteniendo como resultado la cadena original. Mañana comentaré si al final consigo que esto también funcione donde lo necesito.

P.D. Gracias Casimiro por hacerme mirar esto más despacio.
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 02-06-2014 a las 01:18:21.
Responder Con Cita
  #6  
Antiguo 02-06-2014
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.062
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Ya sabes, "vísteme despacio que tengo prisa"
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Recuperar BookMark despues de cerrar dataset... verito_83mdq Varios 10 27-01-2011 00:03:18
Recuperar Informacion despues de un Commit Kipow Firebird e Interbase 2 01-04-2009 19:04:02
Error al Tratar de Almacenar Cadena con Acepto inferno Firebird e Interbase 3 04-10-2006 17:17:40
Recuperar autoinc. después de Insert to aig MS SQL Server 2 22-09-2004 10:41:28
Recuperar autonumericos despues de Borrar, Cancelar ,Ect. IcebergDelphi Varios 1 14-05-2003 07:55:02


La franja horaria es GMT +2. Ahora son las 14:28:06.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi