Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Problemas al tratar de guardar y después recuperar una cadena de texto cifrada (https://www.clubdelphi.com/foros/showthread.php?t=85973)

dec 02-06-2014 22:59:46

Hola,

Cita:

Empezado por Casimiro Notevi (Mensaje 477206)
Puede que esos 60000 caracteres, en su día, surgió de una manera similar a: ¿quién va a necesitar más de 640 Kb? :D

Sí; je je je... pero no puede ser Casimiro. Nada me gustaría más que desentenderme del asunto, y, si existiese esta limitación también en Delphi (tal vez incluso en la "especificación" de "base 64" o algo así) entonces tal vez no quedaría más remedio, pero, parece que esta limitación sólo se da en mi DLL y su relación con el programa "madre" en cuestión. Algo que no tiene lógica si se leen mis anteriores mensajes y que se resume en que podemos pasar cadenas mucho más largas de 60.000 caracteres, pero, por alguna razón, no si esta cadena está codificada en "base 64"... :confused:

Casimiro Noteví 02-06-2014 23:10:50

No sé cómo trabaja tu programa ni el otro, pero ¿cómo sabe ese programa que le están enviando algo en code64 (o code25 o code129, por decir algo) para aceptar 60 mil caracteres o más?

dec 02-06-2014 23:16:43

Hola,

Cita:

Empezado por Casimiro Notevi (Mensaje 477209)
No sé cómo trabaja tu programa ni el otro, pero ¿cómo sabe ese programa que le están enviando algo en code64 (o code25 o code129, por decir algo) para aceptar 60 mil caracteres o más?

Pues... yo creo que en realidad no lo sabe. Y, de saberlo, ¿qué tendría que decir? Es decir, al programa debería darle lo mismo la cadena que se le pasa. Está visto que no le dá lo mismo si se le pasa algo "en binario". Pero el programa puede "recibir" cadenas mucho mayores de 60.000 caracteres... excepto, parece ser, si dichas cadenas están en "base 64".

Ya. Ya sé que esto no tiene sentido. Además, conociendo un poco al programador de NeoBook (y su programa, y que lleva más de 20 años desarrollándolo) me es muy complicado asumir que el "problema" está en la parte que le toca a NeoBook. Quiero pensar y aun pienso que el problema está de mi parte. Ahora bien, dicho esto, que me expliquen lo que está pasando... :confused:

escafandra 03-06-2014 00:12:29

Cita:

Empezado por dec (Mensaje 477205)
Gracias escafandra. Te juro que no sé cómo hacer lo que me sugieres. Otrosí recordemos que yo recibo variables del tipo PChar y no de tipo String. No sé si esto implica algo.

Si conviertes un String a un PCHAR se te trunca la cadena en el primer carácter #0, por eso debes usar un buffer y no un cast:
Ejemplo con PBYTE, pero puedes usar un Pointer...
Código Delphi [-]
procedute PasaBuffer(buffer: PBYTE; Size: integer);
.....
 
PasaBuffer(PBYTE(@MyString[1]), Length(MyString));

Cita:

Empezado por dec (Mensaje 477205)
Por lo demás, si os cuento lo que acabo de hacer no lo creéis. Como he dicho arriba, otra de mis DLL permite al usuario codificar y decodificar en "base 64". Ahora bien, esta DLL usa los componentes Indy para llevarlo a cabo.

Pues bien, he probado a codificar un archivo de texto en "base 64" con una de estas acciones, es decir, enviar al programa "madre" la cadena codificada (no cifrada) en "base 64", y, ¿y qué diréis que ha pasado? Exacto: no puedo enviar más de 60.000 caracteres exactos.

O sea, suponiendo que algún usuario de dicha DLL quisiera codificar más de 60.000 caracteres se encontraría con el problema de no poder hacerlo... por si tenía poco con un problema, ahora acaso tengo dos. ¡Toma ya!

¿Pero qué demonios significa esta limitación de 60.000 caracteres? ¿Por qué, exactamente, 60.000 caracteres? ¿Cómo es que dicha limitación existe si se usa Indy como si se usa la unidad que he enlazado más arriba?

Has probado a usar la API de Windows: CryptBinaryToString y CryptStringToBinary
Ejemplo:
Código Delphi [-]
function Base64Encode(S: String): String;
var
  Size: DWORD;
begin
  if CryptBinaryToString(@S[1], Length(S), CRYPT_STRING_BASE64 ,nil, Size) then
  begin
    SetLength(Result, Size-1);
    if not CryptBinaryToString(@S[1], Length(S), CRYPT_STRING_BASE64, PChar(Result), Size) then
      Result:= EmptyStr;
  end;
end;


Saludos.

dec 03-06-2014 00:51:28

Hola a todos,

Gracias escafandra. Aunque no comprendo muy bien de lo que se trata, sí sé que NeoBook usa ciertas funciones para "pasar" variables (funciones que nosotros los desarrolladores de DLL's tenemos que usar obligatoriamente), y, lo hace de forma muy similar a como tú dices. O sea, en realidad no me queda claro si podría hacer lo que tú me propones, pero, trataré de investigarlo. Pero, es que ahora ya casi estoy loco del todo, porque, probando a codificar/decodificar cadenas con mis DLL en Windows 7.... no tengo la limitación de 60.000 caracteres. Esto es verdaderamente para acabar atado.

¿Recuerda alguien que ayer comenté que había inconsistencias entre Windows 7 y Windows 8 que yo no podía entender? Parecía que se habían superado (de forma irracional, cambiando de los componentes Indy a otros) pero nada más lejos de la realidad. El asunto es que ahora mismo no sé ni cómo enfocar el problema: ¿resulta que en Windows 7 funciona algo que no funciona en Windows 8? ¿Algo tan "sencillo" como codificar y decodificar en "base 64"? Simplemente no me lo creo.

Así que mañana (espero poder dejar esto por hoy y relajarme/ros un poco) quiero "terminar" la DLL y probarla en Windows 7 y Windows 8,... y ver qué pasa.

Ya os contaré... :(

¡Gracias de nuevo a todos!

dec 03-06-2014 22:19:45

Hola,

No os quiero dejar con las ganas de saber que al final he conseguido subsanar el problema. Con la ayuda de todos. Hay cosas que todavía no consigo comprender. Por ejemplo, ya no uso Indy para codificar en "base 64", pero, creo que no se trata de un problema de Indy, sino de cómo se comporta el programa "madre" de mi DLL. El caso es que, como suele pasar, desafortunadamente, más de una vez (por lo menos a tipos como a mí), todo se debía a un "malentendido".

En efecto, imaginaros la situación:

1º Tengo dos casillas en una aplicación y dos botones: cifrar y descifrar.

2º Cifro el texto de la primera casilla, lo codifico en "base 64" y lo sitúo en la segunda casilla.

3º Descifro el texto de la segunda casilla para obtener el texto original.

Hasta aquí todo correcto, excepto la inquietante cifra máxima de 60.000 caracteres. En efecto, nunca puedo obtener texto en claro más allá de esa cifra, y, de hecho la segunda casilla nunca llega a guardar más de esa misma cifra. ¿Qué está pasando aquí?

Lo más obvio (ahora que se sabe): ¡las casillas del programa "madre" de mi DLL están configuradas, por defecto, para tener ese límite máximo de caracteres!

En fin, no voy a decir que la ayuda del programa está errada en esta cuestión pues indica que si se establece como límite un "0", esto significa que no hay límite... pero lo cierto es que sí que lo hay (60.000) si se deja tal cual ese "0". Como digo la ayuda está errada, pero, no voy a culparla porque yo ni siquiera he mirado ahí.

He tenido que hacer varias pruebas por mi cuenta para llegar a dicha conclusión. Y bueno, al final el problema se ha solucionado, aunque, como he dicho más arriba, no uso Indy para realizar la codificación, sino esta otra unidad (espero no estar infringiendo copyright alguno...), que usa la API de Windows y funciona como se espera: aunque insisto en que muy probablemente Indy funciona bien y el fallo está en otro sitio, pero, no tengo tiempo ni ganas para ponerme ahora a investigar sobre este asunto, mucho menos después de haber comprendido y solucionado el problema.

¡Gracias a todos vosotros! :)

Casimiro Noteví 03-06-2014 22:58:20

Todo tiene solución :), bueno, casi todo :( :p ;)

dec 03-06-2014 23:34:09

Hola,

Cita:

Empezado por Casimiro Notevi (Mensaje 477271)
Todo tiene solución :), bueno, casi todo :( :p ;)

¿Para qué preocuparnos por lo que tiene solución o por lo que no la tiene? Algo así dicen que dijo un mono sabio. Pero quien no es profesional corre el riesgo de entrar en miedo pánico. ¡Piensa que acaba de abrirse la tierra bajo sus pies! Un error que se añade al primero: errores. Pero en fin... al menos espero haber aprendido algo esta vez.

¡Gracias a todos! :)

Casimiro Noteví 03-06-2014 23:37:54

Cita:

Empezado por dec (Mensaje 477277)
¿Para qué preocuparnos por lo que tiene solución o por lo que no la tiene? Algo así dicen que dijo un mono sabio.

Vaya, yo siempre he dicho eso :o

:D:p

dec 03-06-2014 23:43:07

Cita:

Empezado por Casimiro Notevi (Mensaje 477278)
Vaya, yo siempre he dicho eso :o

:D:p

Bueno; es que todos somos monos... y algunos más sabios que otros. :D

escafandra 04-06-2014 01:40:15

Cita:

Empezado por dec (Mensaje 477269)
... al final el problema se ha solucionado, aunque, como he dicho más arriba, no uso Indy para realizar la codificación, sino esta otra unidad (espero no estar infringiendo copyright alguno...), que usa la API de Windows y funciona como se espera...

Esa unit dista bien poco del código que te dejé aunque no testa el fallo en la llamada a la API.

Ten en cuenta que base64 no es un sistema seguro de encriptación, no se si esto es importante para tu propósito.

Me alegra que hayas encontrado la solución. :)


Saludos.

roman 04-06-2014 05:52:00

Yo lo que entendí es que está haciendo ambas cosas: cifrar y codificar en base 64.

// Saludos

dec 04-06-2014 11:25:07

Hola a todos,

Cita:

Empezado por escafandra (Mensaje 477281)
Esa unit dista bien poco del código que te dejé aunque no testa el fallo en la llamada a la API.

Ten en cuenta que base64 no es un sistema seguro de encriptación, no se si esto es importante para tu propósito.

Me alegra que hayas encontrado la solución. :)


Saludos.

Gracias escafandra. En efecto me decidí por la unidad referida por usar la API de Windows, tal como aconsejaste. Además encontré útil la unidad puesto que implementa las dos funciones necesarias, con ciertos añadidos, además, que acaso también puedan servirme de algo. Respecto de que habría que validar la API, llevas razón, y seguramente haré los cambios necesarios para que se lleve a cabo. Espérate que no envuelva la unidad en una clase que ofrezca varias características. :)

Cita:

Empezado por roman (Mensaje 477289)
Yo lo que entendí es que está haciendo ambas cosas: cifrar y codificar en base 64.

// Saludos

Eso es Román. Primero la cadena se cifra con un determinado algoritmo, y, después, para poder guardar el resultado (el texto cifrado) en una cadena de texto (y no en binario) se codifica en "base 64". :)

¡Gracias de nuevo a todos! ;)

Julián 04-06-2014 12:05:08

Yo tuve los mismos problemas y también los solucioné usando base64. De hecho, hace muy poquito he vuelto a tenerlos, en javascript y php: en la nueva versión de gestor de contenidos/framework o lo que sea, existe la opción de guardar la contraseñas cifradas en una cokie y tambien se cifra antes de enviarla mediante post al hacer login. Bien, pues también uso Base64 para convertir a string.
Ah, y en Delphi tampoco usaba Indy, sino una función hecha en object Pascal, que alguien escribió alguna vez.

dec 04-06-2014 13:08:01

Hola,

Así es Julián, no somos pocos los que nos hemos topado con este problema y hemos tomado "base 64" como solución. :)


La franja horaria es GMT +2. Ahora son las 05:20:14.

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