Ir al contenido



Foto

Pasar función Pascal a php


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

#1 el-mono

el-mono

    Advanced Member

  • Miembros
  • PipPipPip
  • 116 mensajes

Escrito 10 mayo 2018 - 05:01

Hola gente, tengo un pequeño sistema el cual tiene una función para desencriptar una cadena de texto. 

Lo que necesito es pasar esa función a su equivalente para un sistema en php. Alguien me podría dar una mano porque vengo muy perdido en el tema.


delphi
  1. function desencriptar(aStr: String; aKey: Integer): String;
  2. begin
  3. Result:='';
  4. RandSeed:=aKey;
  5. for aKey:=1 to Length(aStr) do
  6. Result:=Result+Chr(Byte(aStr[aKey]) xor random(256));
  7. end;

Lo que tengo armado hasta aquí pero me da error es lo siguiente:


php
  1. <?php
  2. function desencriptar($cadena){
  3. $key=''; // Una clave de codificacion, debe usarse la misma para encriptar y desencriptar
  4. $aKey = 10;
  5. for($aKey = 1; $aKey < count($cadena); ++$aKey) {
  6. $Result=$Result+Chr(Byte($cadena[$aKey]) xor rand(256,256));
  7. }
  8. return $result; //Devuelve el string desencriptado
  9.  
  10. }
  11.  
  12. $texto = "aau";
  13.  
  14.  
  15. // Desencriptamos el texto
  16. $texto_original = desencriptar($texto);
  17.  
  18. echo $texto_original
  19. ?>


  • 0

#2 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.155 mensajes
  • LocationArgentina

Escrito 10 mayo 2018 - 09:06

Hola el-mono,

Veo unas cuantas cosas para observarte, pero hay dos problemas importantes:

1. Para concatenar cadenas en PHP se utiliza el punto. Por ejemplo, algo que en Pascal hacemos así:


delphi
  1. result := result + ' Algo';

En PHP es:


php
  1. $result .= $algo;

2. Si bien el algoritmo es trasportable no necesariamente lo será el texto cifrado. Esto es porque Pascal y PHP poseen diferentes algoritmos en sus funciones random. De modo que obtendrás resultados distintos en cada lenguaje. Por tanto lo que cifres con cada lenguaje será solamente descifrable consigo mismo. Si la idea es cifrar contenido de forma independiente de plataformas, lenguajes, etc. lo mejor sería que mirases en implementaciones profesionales diseñadas para eso. Una buena práctica es utilizar bcrypt, que está implementado ya en varios lenguajes, siendo PHP uno de ellos.

 

Otras cosillas para remarcar son:

3. En el algoritmo en Pascal estás aparentemente restableciendo la semilla del generador aleatorio. En su versión PHP no. Pero además,

4. En el algoritmo en Pascal pasas como parámetro este valor como Key, pero en el de PHP no.

5. Estás reusando la variable que supuestamente será como clave para el contador en el ciclo for. No es pecado hacer esto, pero puede llevar a confusiones. No cuesta nada destinar una variable auxiliar, el típico i, o $i para el caso de PHP. Esto además lleva a código seguro.

 

Por ahora eso puedo decirte.

 

Saludos,


  • 0

#3 seoane

seoane

    Advanced Member

  • Administrador
  • 1.243 mensajes
  • LocationEspaña

Escrito 11 mayo 2018 - 09:32

Vamos a ver si te sirve


php
  1. <?php
  2.  
  3. $rand_seed = 123456;
  4.  
  5. function get_seed() {
  6. global $rand_seed;
  7. $rand_seed = $rand_seed * 134775813 % 0x100000000 + 1;
  8. return $rand_seed;
  9. }
  10.  
  11. function delphi_rnd() {
  12. return get_seed() * 2.32830643653870e-10;
  13. }
  14.  
  15. function delphi_random($range) {
  16. return intval(delphi_rnd() * $range);
  17. }
  18.  
  19. function cifrar($texto, $clave) {
  20. global $rand_seed;
  21.  
  22. $res = '';
  23. $rand_seed = $clave;
  24. for ($i = 0; $i <= strlen($texto) - 1; $i++) {
  25. $res .= $texto{$i} ^ Chr(delphi_random(256));
  26. }
  27. return $res;
  28. }
  29.  
  30. $cifrado = cifrar("Hola mundo", 123456);
  31. echo $cifrado . "\n";
  32. $descifrado = cifrar($cifrado, 123456);
  33. echo $descifrado . "\n";

Por si lo quieres probar: http://sandbox.onlin...0bb16f5207519d1

 

Usa el mismo algoritmo de "random" que delphi. El unico inconveniente es tener una variable global.

 

Saludos

 

PD: Este es el codigo que utilice para probar los resultados:


delphi
  1. function desencriptar(aStr: String; aKey: Integer): String;
  2. begin
  3. Result:='';
  4. RandSeed:=aKey;
  5. for aKey:=1 to Length(aStr) do
  6. Result:=Result+Chr(Byte(aStr[aKey]) xor random(256));
  7. end;
  8.  
  9. var
  10. str: String;
  11. begin
  12. str:= desencriptar('Hola mundo', 123456);
  13. writeln(str);
  14. str:= desencriptar(str, 123456);
  15. Writeln(str);
  16. Readln;
  17. end.

En ambos casos da:


php
  1. BùtCe-â÷/9
  2. Hola mundo


  • 0

#4 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.155 mensajes
  • LocationArgentina

Escrito 11 mayo 2018 - 10:03

 

Vamos a ver si te sirve


php
  1. <?php
  2.  
  3. $rand_seed = 123456;
  4.  
  5. function get_seed() {
  6. global $rand_seed;
  7. $rand_seed = $rand_seed * 134775813 % 0x100000000 + 1;
  8. return $rand_seed;
  9. }
  10.  
  11. function delphi_rnd() {
  12. return get_seed() * 2.32830643653870e-10;
  13. }
  14.  
  15. function delphi_random($range) {
  16. return intval(delphi_rnd() * $range);
  17. }
  18.  
  19. function cifrar($texto, $clave) {
  20. global $rand_seed;
  21.  
  22. $res = '';
  23. $rand_seed = $clave;
  24. for ($i = 0; $i <= strlen($texto) - 1; $i++) {
  25. $res .= $texto{$i} ^ Chr(delphi_random(256));
  26. }
  27. return $res;
  28. }
  29.  
  30. $cifrado = cifrar("Hola mundo", 123456);
  31. echo $cifrado . "\n";
  32. $descifrado = cifrar($cifrado, 123456);
  33. echo $descifrado . "\n";

Por si lo quieres probar: http://sandbox.onlin...0bb16f5207519d1

 

Usa el mismo algoritmo de "random" que delphi. El unico inconveniente es tener una variable global.

 

Saludos

 

PD: Este es el codigo que utilice para probar los resultados:


delphi
  1. function desencriptar(aStr: String; aKey: Integer): String;
  2. begin
  3. Result:='';
  4. RandSeed:=aKey;
  5. for aKey:=1 to Length(aStr) do
  6. Result:=Result+Chr(Byte(aStr[aKey]) xor random(256));
  7. end;
  8.  
  9. var
  10. str: String;
  11. begin
  12. str:= desencriptar('Hola mundo', 123456);
  13. writeln(str);
  14. str:= desencriptar(str, 123456);
  15. Writeln(str);
  16. Readln;
  17. end.

En ambos casos da:


php
  1. BùtCe-â÷/9
  2. Hola mundo

 

¿El random de que versión de Delphi?

 

Solo una cosilla:

Es muy probable que la función random cambie de versión a otra. Por lo que el random() de D7 no necesariamente sea el mismo que el de RAD Studio Tokyo 10.2.3.

Y esto también va para PHP

¿Que garantías hay de que el algoritmo sea el mismo? Ninguna.

Es más en Delphi se ha cambiado el generador con cada versión.Hagan pruebas si quieren. Asi que si se va a generar archivos cifrados hay que tener cuidado. Imaginate, hoy escribes esa función usando D 10.2.3 y PHP 5.5.23 pero luego cambias a PHP 7.5 y resulta ser que lo cifrado antes ya no funca.

 

La lección acá es NO DEPENDER de las funciones genéricas de generación de valores aleatorios de los lenguajes. ¡Sobre todo en el contexto de cifrado!

 

Saludos,


  • 0

#5 seoane

seoane

    Advanced Member

  • Administrador
  • 1.243 mensajes
  • LocationEspaña

Escrito 11 mayo 2018 - 10:36

Hola Delphius,

 

no estoy defendiendo la bondad del algoritmo, de hecho es una basura, pero se me ocurren escenarios donde sea necesario usarlo, por ejemplo si tienes un sistema heredado que lo utilice, o tienes que acceder a una base de datos donde se guarden campos cifrados de esa manera. No siempre podemos escoger las herramientas con las que trabajamos.

 

No se cual es el caso del compañero el-mono, pero entiendo que se trata de un sistema que a heredado, por eso mi respuesta.

 

Si estuviera empezando de cero, o estuviera en posicion de escoger, claro que no le aconsejaria utilizar este cifrado (si le podemos llamar asi). Como ya señalaste es dependiente de una funcion "random" que es dependiente de una plataforma en concreto y que ademas es bastante insegura, no es criptograficamente aceptable ni de lejos. Ademas el propio algoritmo es bastante lamentable ya que cifra cada byte por separado en vez de en bloque, y no tiene en cuenta casos como el que unos de los caracteres resultantes sea #0 con los consiguientes problemas que eso puede traer. En fin lo podemos criticar todo l oque quieras y mas ;)

 

Por otro lado. Si esta en la privilegiada posicion de escoger el mismo el metodo de cifrado yo le recomendaria AES256, un metodo de cifrado simetrico, seguro y certificado, un estandar a dia de hoy. No le recomendaria enb cambio BCrypt, que hasta donde yo se es un algoritmo de hash y no de cifrado.

 

Como ya dije no siempre podemos escoger con que trabajamos.

 

Saludos

 

PD: No se con que version de delphi es compatible. Yo utilice la version que esta en la wiki de lazarus como "compatible" con delphi, y la probe en un Delphi 10.2 Tokio, no dispongo de otras versiones ahora mismo.


  • 0

#6 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.155 mensajes
  • LocationArgentina

Escrito 11 mayo 2018 - 12:30

Hola Delphius,

 

no estoy defendiendo la bondad del algoritmo, de hecho es una basura, pero se me ocurren escenarios donde sea necesario usarlo, por ejemplo si tienes un sistema heredado que lo utilice, o tienes que acceder a una base de datos donde se guarden campos cifrados de esa manera. No siempre podemos escoger las herramientas con las que trabajamos.

 

No se cual es el caso del compañero el-mono, pero entiendo que se trata de un sistema que a heredado, por eso mi respuesta.

 

Si estuviera empezando de cero, o estuviera en posicion de escoger, claro que no le aconsejaria utilizar este cifrado (si le podemos llamar asi). Como ya señalaste es dependiente de una funcion "random" que es dependiente de una plataforma en concreto y que ademas es bastante insegura, no es criptograficamente aceptable ni de lejos. Ademas el propio algoritmo es bastante lamentable ya que cifra cada byte por separado en vez de en bloque, y no tiene en cuenta casos como el que unos de los caracteres resultantes sea #0 con los consiguientes problemas que eso puede traer. En fin lo podemos criticar todo l oque quieras y mas ;)

 

Por otro lado. Si esta en la privilegiada posicion de escoger el mismo el metodo de cifrado yo le recomendaria AES256, un metodo de cifrado simetrico, seguro y certificado, un estandar a dia de hoy. No le recomendaria enb cambio BCrypt, que hasta donde yo se es un algoritmo de hash y no de cifrado.

 

Como ya dije no siempre podemos escoger con que trabajamos.

 

Saludos

 

PD: No se con que version de delphi es compatible. Yo utilice la version que esta en la wiki de lazarus como "compatible" con delphi, y la probe en un Delphi 10.2 Tokio, no dispongo de otras versiones ahora mismo.

 

Si se trata de un sistema heredado, y por sobre todo si ya ha estado en producción (en uso real por parte de los usuarios) y por tanto generandose cifrados no queda otra que mantener el algoritmo original. ¡El problema es que no sabemos realmente que versión de Delphi ha usado! Por lo que ese random es motivo de un gran problema.

 

No era mi intención ofenderte ni causar problemas, solamente quiero mostrar la debilidad y el principal inconveniente aquí. Que es usar ese random() tan cambiante. No es seguro en asboluto su uso.

Como dices, si es por ser profesionales, hay que recurrir a opciones estudiadas, probadas y que sean estandarizadas. AES256 sigue siendo una opción muy segura (*). No se porqué se me vino a la cabeza bcrypt... ¡tienes razón es un algoritmo de hash! Ando con pocas neuronas. ¡mil disculpas!

 

No se que Wiki has consultado la verdad. Pero el algoritmo random que emplea Lazarus es un Mersenne TWister mt19937 mientras que los de Delphi han sido históricamente Congrencuiales Multiplicativos al que le fueron cambiando los parámetros. Si resulta ser que hay una coindicencia entre alguna versión del Congruencial Multiplicativo que iguale al MT19937 lo desconozco.

 

Saludos,

 

(*) Se han reportado sus debilidades y ya se han roto algunas de sus piezas. Pero el corazón en si de su médodo todavía no ha caído.


  • 0

#7 seoane

seoane

    Advanced Member

  • Administrador
  • 1.243 mensajes
  • LocationEspaña

Escrito 11 mayo 2018 - 06:04

No se que Wiki has consultado la verdad.

 

Esta: http://wiki.freepasc...ible_LCG_Random

Que a su vez saca los datos de esta: https://en.wikipedia...ntial_generator

 

 

(*) Se han reportado sus debilidades y ya se han roto algunas de sus piezas. Pero el corazón en si de su médodo todavía no ha caído.

 

Y esperemos que tarde en caer es el estandar tanto millitar como civil. Y esta presente en millones de dispositivos

 

Saludos


  • 1

#8 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.155 mensajes
  • LocationArgentina

Escrito 11 mayo 2018 - 06:37

Esta: http://wiki.freepasc...ible_LCG_Random

Que a su vez saca los datos de esta: https://en.wikipedia...ntial_generator

 

 

 

Y esperemos que tarde en caer es el estandar tanto millitar como civil. Y esta presente en millones de dispositivos

 

Saludos

 

Gracias por el dato.

Ojalá que tarde pero no hay que confiarse demasiado...

Hace unos cuantos años ya un tipo demostró que tiene una falla en su matemática, pero que no estaba siendo explotable. PERO recientemente, algunos meses, mientras leía algunos tuits de algunos especialistas en seguridad informática me enteré de que ya se reportó el primer quiebre usando esa falla, para un caso particular. Recuerdo haber leído que se está analizando si es generalizado. Que es lo más probable.

 

Asi que quizá sea hora de empezar a mirar con reojo la posibilidad de aumentar el tamaño, aunque también se sabe que resultó ser que AES256 es matemáticamente más seguro que su versión 512. O utilizar otro más robusto, o al que no le hayan encontrado algún bug todavía.

 

Estos hackers que andan bastante loquillos ultimamente....

 

Saludos,


  • 0

#9 el-mono

el-mono

    Advanced Member

  • Miembros
  • PipPipPip
  • 116 mensajes

Escrito 12 mayo 2018 - 09:21

Gente muchas gracias por ayudarme. Muchas gracias por dedicar un tiempo en sus respuestas


  • 0