Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Temas relacionados > Seguridad
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 28-03-2007
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 19.438
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por dec
Alguna forma ha de haber de lograr hacer desaparecer de la memoria el número de serie correcto una vez utilizado por el programa.
¿Y si enfocamos el tema de otra manera?
En lugar de borrarlo, que no aparezca. Tal vez me he perdido algo, pero creo que es posible...

Se trata de hacer el cálculo sin asignar el SN en ningun sitio.
Por ejemplo, este programa; He seguido los pasos (con el WinHex) para encontrar en Serial Correcto en memoria y yo no lo veo.

El procedimiento de cálculo es el siguiente:

Código Delphi [-]
var
  b:Boolean;
  i:Integer;
begin

  if ((Length(Edit2.Text) - Length(Edit1.Text)) < 2) or
     (Length(Edit1.Text) < 4) then begin
    MessageDlg('El número de registro es incorrecto', mtWarning, [mbOK], 0);
    Exit
  end;

  b := True;

  for i := 0 to (Length(Edit1.Text) - 1) do begin
    b := b and (Edit1.Text[i] = Edit2.Text[i]);
  end;

  b := b and (Edit2.Text[i + 1] = 'S');
  b := b and (Edit2.Text[i + 2] = 'N');

  if (b) then begin
    MessageDlg('El registro se ha completado correctamente.', mtInformation, [mbOK], 0);
  end
  else begin
    MessageDlg('El número de registro es incorrecto', mtWarning, [mbOK], 0);
  end;

Como véis es muy "cutre", pero el número correcto no se asigna.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #2  
Antiguo 28-03-2007
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 19.438
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Dista mucho de ser infalible (1) y (2), pero creo que la solución puede ir por aquí.

(1) Comprobación de la longitud. (pepito + palotes); Se pueden ver los registros con los valores 7 y 6 (de ambas longitudes), la resta y la comparación con 2.
(2) Comprobación de caracteres 1 a 1. (1234 + casaca); Se puede ver cómo empieza a comparar "1" y "c" y el salto que nos lleva al mensaje de fallo.

Creo que la idea es buena.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 28-03-2007
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.142
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

No lo cojo Neftalí. En tu anterior ejemplo (que te agradezco) según se ve en el código puede registrarse el programa con el usuario "pepe" y el número de serie "pepeSN". Claro que lo sé porque tengo acceso al código fuente, en esto estamos de acuerdo.

Yo comprendo que ha de haber alguna forma de hacer lo que necesito, puesto que hay programas que me consta no caen en la "trampa" en la que cae el mío. Sin embargo por más que lo intento aún no consigo resultados.

Ten en cuenta que no se trata de comparar el valor "clave de usuario" y "número de serie". Se trata de que a una clave de usuario dada le corresponde un número de serie. El programa se encarga, a partir de la clave de usuario y un número "base", se encarga, digo, de generar el número de serie.

Yo tengo el programa y un generador de números de serie, que es otro programa. Ambos comparten la unidad "GenerarSerial" y en esta unidad hay una clase con dos métodos: "CompararSerials" y "GeneralSerial". Cuando ejecuto el generador lo que estoy haciendo es obtener un número de serie según la clave de un usuario.

El usuario me escribe: "Oyes David, este programa está molón, acabo de ingresarte en tu cuenta 1.000.000 de dólares, espero que sea suficiente para que me envíes un número de serie a nombre de "Pepe Rico".

Yo cojo el Generador e introduzco el número base del programa y la clave de usuario "Pepe Rico". El Generador me genera (toma ya) un número de serie para esa clave y ese número base y yo se lo mando a Pepe Rico: "Hola Pepe, recibido el millón ahí te va el número de serie".

El programa (ya no el Generador de "Serials"), cuando Pepe Rico introduzca su clave de usuario y su número de serie podrá comprobar si este último se corresponde con el que tiene que ser puesto que podrá calcular (como el Generador) el correcto en base al número base y a la clave de usuario introducida.

Hasta ahí bien. Todo es correcto. ¿Todo? No. Porque que el Generador deje en memoria el número de serie correcto no importa. De hecho tiene que ofrecerme ese número de serie correcto, tiene que dejarme "copiarlo" (de hecho se muestra en un "TEdit") para que yo pueda mandárselo a Pepe Rico que para eso pagó el millón de rupias.

Ahora bien, el programa, el de Pepe Rico, no el Generador, no debe (y no lo hace) mostrar el número de serie correcto al usuario... ¡pero este se queda en la memoria! Y tal vez Pepe Rico no, pero algún otro usuario conseguirá el número de serie correcto a poco que eche un vistazo...

Lo último que he probado ha sido el "CheckSum", el "hash" del número de serie, pero es que no salimos del problema: Yo puedo comparar el "CheckSum" del número de serie del usuario y del correcto, pero si puedo hacer esto último es porque he generado el número de serie correcto, y, según parece, a poco que esto se haga y se haga donde se haga ya aparecerá en memoria... irremediablemente.

Tal vez es que el planteamiento es el equivocado. Ya digo que todo mi "sistema de generación y comprobación de números de serie" se basa en el código del componente "TJvSerialMaker" de la Jedi VCL. Pero entonces es que todo programa que haga uso de este componente está comprometido en lo dicho: mostrará el número de serie correcto en la memoria.

Tal vez sea esto y no tenga remedio porque es un mal planteamiento o no está lo suficientemente pensado o simplemente es algo sencillo, de andar por casa, puesto que a Pepe Rico probablemente no mirará la memoria RAM ni sabrá siquiera que algo así existe y se puede mirar...

¡Arrggggggggggggggggggggg!
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #4  
Antiguo 28-03-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 26
seoane Va por buen camino
Si no es mucho preguntar, como generas el numero de serie. Puede que el problema resida ahí. Podríamos intentar crear un algoritmo, una sola función, que permita comprobar el numero de serie dejando la memoria limpia.

En resumen, muestranos el algoritmo
Responder Con Cita
  #5  
Antiguo 28-03-2007
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.142
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Ningún problema Seoane... es de dominio público... ya digo. Extraído de la unidad "JvSerialMaker.pas" de la Jedi Library. De hecho copiaré aquí los dos métodos principales... el que genera números de serie y el que compara un número de serie con el "correcto" (generado)...

Código Delphi [-]
function TJvSerialMaker.GiveSerial(ABase: Integer; AUserName: string): string;
var
  A: Integer;
begin
  if (ABase <> 0) and (AUserName <> '') then
  begin
    A := ABase * Length(AUserName) + Ord(AUserName[1]) * 666;
    Result := IntToStr(A) + '-';
    A := ABase * Ord(AUserName[1]) * 123;
    Result := Result + IntToStr(A) + '-';
    A := ABase + (Length(AUserName) * Ord(AUserName[1])) * 6613;
    Result := Result + IntToStr(A);
  end
  else
    Result := RsError;
end;

function TJvSerialMaker.SerialIsCorrect(ABase: Integer; AUserName: string; Serial: string): Boolean;
begin
  if (AUserName <> '') and (ABase <> 0) then
    Result := Serial = GiveSerial(ABase, AUserName)
  else
    Result := False;
end;

Como se ve se parte de un número "base" que ha de ser constante tanto en el programa generador de números de serie como en el programa a "proteger"... Ambos programas, pues, comparten el código anterior. A partir del número base y de una clave de usuario, como puede verse el primer método genera un número de serie: justamente el que corresponde a la clave de usuario + número base.

Así se consigue que tanto el programa generador de números de serie como el programa a "proteger" puedan obtener de una clave de usuario un número de serie, el mismo que ha de compararse con el que el usuario introduzca. Todo esto funciona correctamente, si no fuera porque el número de serie correcto (y justo el cuando se genera en el primer método) queda en la memoria.

Y es en el primer método donde queda el número en memoria, porque puede verse que en el método el número de serie se va generando "a trocitos", que al cabo son unidos: pues bien, en la memoria aparecen todos los trocitos... e incluso el resultado final: el número de serie correcto para cualquier clave de usuario introducida.
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 28-03-2007 a las 18:17:37.
Responder Con Cita
  #6  
Antiguo 28-03-2007
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.142
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Ya me estoy volviendo loco. Resulta que utilizo el "JvSerialMaker" desde hace cierto tiempo... y me ha dado por comprobar en un antiguo programa que lo utilizaba a ver si era capaz de sacar el número de serie de la memoria... ¡pero no he podido hacerlo!

Y a dios pongo por testigo que ambos programas: tanto el antiguo como el nuevo, utilizan el mismo sistema... eso sí, el antiguo utiliza el "JvSerialMaker" tal cual, y este nuevo utiliza una "adaptación" que le he hecho por mi cuenta... ¡pero los métodos para generar el número de serie y para comprobarlo son prácticamente iguales!

No cambia nada. De hecho la adaptación que he hecho de "JvSerialMaker" se limita a desligarlo de la Jedi VCL (quitando toda referencia a esta) y a retirar las propiedades del componente para quedarme sólo con los dos métodos comentados.

¿Y sin embargo en el programa antiguo no consigo ver el número de serie en la memoria y en el programa nuevo sí? ¡Esto es de locos!

Sé que no es de locos, sino todo lo contrario. Pero yo estoy cansado. Y así me las gasto en estas circustancias...

Aquí puede verse la adaptación de "JvSerialMaker" que llevo a cabo; compárese con el "JvSerialMaker" original... yo creo que no hay cambio que justifique que ahora el sistema se haya vuelto "inseguro"...

Código Delphi [-]
unit UGeneradorSeriales;

interface

type
  TGeneradorSeriales = class
  public
    function ObtenerNumeroSerie(numeroBase:integer;
     claveUsuario: string): string;

    function ComprobarNumeroSerie(numeroBase: integer;
     claveUsuario: string; numeroSerie: string): boolean;
  end;

implementation

uses
  SysUtils;

function TGeneradorSeriales.ObtenerNumeroSerie
 (numeroBase: integer; claveUsuario: string): string;
var
  i: integer;
begin
  result := '';
  if (numeroBase <> 0) and (claveUsuario <> '') then
  begin
    i := numeroBase * Length(claveUsuario) + Ord(claveUsuario[1]) * 156;
    result := IntToStr(i);
    i := numeroBase * Ord(claveUsuario[1]) * 452;
    result := Result + IntToStr(i);
    i := numeroBase + (Length(claveUsuario) * Ord(claveUsuario[1])) * 3674;
    result := result + IntToStr(i);
    result := StringReplace(result, '-', '', [rfReplaceAll]);
  end;
end;

function TGeneradorSeriales.ComprobarNumeroSerie(numeroBase: integer;
 claveUsuario: string; numeroSerie: string): boolean;
begin
  if (numeroBase <> 0) and (claveUsuario <> '') then
    result := (numeroSerie = Self.ObtenerNumeroSerie(numeroBase, claveUsuario))
  else
    result := false;
end;

end.
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 28-03-2007 a las 18:35:16.
Responder Con Cita
  #7  
Antiguo 28-03-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 26
seoane Va por buen camino
Bueno dec, aquí te dejo una función para comprobar el numero de serie pero sin llegar a generarlo en ningún momento. La función para generarlo sigue siendo la misma que pones en el mensaje #40, y puedes usarla tu para generar los números de serie que le mandes a los clientes.
Código Delphi [-]
function GetNum(var Str: String): Integer;
var
  i: Integer;
begin
  Result:= 0;
  while TryStrToInt(Copy(Str,1,1),i) do
  begin
    Result:= (Result * 10) + i;
    Delete(Str,1,1);
  end;
  Delete(Str,1,1);
end;

function CheckSerial(ABase: Integer; AUsername, ASerial: string): Boolean;
var
  A: Integer;
begin
  Result:= FALSE;
  if (ABase <> 0) and (AUserName <> '') then
  begin
    A:= ABase * Length(AUserName) + Ord(AUserName[1]) * 666;
    Result:= GetNum(ASerial) = A;
    A := ABase * Ord(AUserName[1]) * 123;
    Result:= Result and (GetNum(ASerial)= A);
    A := ABase + (Length(AUserName) * Ord(AUserName[1])) * 6613;
    Result:= Result and (GetNum(ASerial) = A);
  end;
end;
Bueno, ahora ya no aparece el numero de serie en la memoria. Ya solo nos tiene que preocupar que nos parchee el programa algún ruso con mucho tiempo libre .
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

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
eliminar datos con dbgrid UREÑA Conexión con bases de datos 20 30-03-2007 23:41:32
Eliminar Datos eficientemente k_rito Conexión con bases de datos 5 27-11-2006 00:44:45
Cómo obtener ciertos datos de los archivos ejecutables y librerías StartKill Varios 1 14-08-2006 23:10:01
Eliminar del memoria los querys Aura OOP 4 01-04-2004 17:40:40
Eliminar datos de una tabla DBF vicvil Tablas planas 4 16-05-2003 21:17:46


La franja horaria es GMT +2. Ahora son las 00:50:23.


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
Copyright 1996-2007 Club Delphi