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 dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.141
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
  #2  
Antiguo 28-03-2007
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.141
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
  #3  
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
  #4  
Antiguo 28-03-2007
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is online now
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 19.437
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
Segun lo que hemos comentado, cambiando un poco la función y añadiendo un parámetro, puedes obtener el número "a trozos".
Revisa este ejemplo.

La de obtener el serial quedaría así:

Código Delphi [-]
function GiveSerial(ABase: Integer; AUserName: string; APart:Integer): string;
const
  RsError = 'Error en los parámetros.';
var
  A: Integer;
begin
  if (ABase <> 0) and (AUserName <> '') then
  begin
    if (APart = 1) then begin
      A := ABase * Length(AUserName) + Ord(AUserName[1]) * 666;
      Result := IntToStr(A);
      Exit;
    end;

    if (APart = 2) then begin
      A := ABase * Ord(AUserName[1]) * 123;
      Result := IntToStr(A);
      Exit;
    end;

    if (APart = 3) then begin
      A := ABase + (Length(AUserName) * Ord(AUserName[1])) * 6613;
      Result := IntToStr(A);
      Exit;
    end;
  end
  else
    Result := RsError;
end;

Y en este caso cambiaríamos la de comprobación por algo así:

Código Delphi [-]
var
  Str, Str2: String;
  i, l1, l2:Integer;
  j1, j2, j3, j4:Integer;
begin

  Str := GiveSerial(123456, Edit1.Text, 1);
  Str2 := Copy(Edit2.Text, 1, Length(Str));

  if (Str <> Str2) then begin
    MessageDlg('SN incorrecto.', mtError, [mbOK], 0);
    Exit;
  end;

  l1 := Length(Str);
  Str := GiveSerial(123456, Edit1.Text, 2);
  Str2 := Copy(Edit2.Text, l1 + 2, Length(Str));

  if ((StrToIntDef(Str, 0) - StrToIntDef(Str2, -99)) <> 0) then begin
    MessageDlg('SN incorrecto.', mtError, [mbOK], 0);
    Exit;
  end;

  l2 := Length(Str);
  Str := GiveSerial(123456, Edit1.Text, 3);
  Str2 := Copy(Edit2.Text, l1 + l2 + 3, Length(Str));

  j1 := StrToIntDef(Str, 0);
  j2 := StrToIntDef(Str2, -99);
  j3 := (j1 DIV j2);
  j4 := (j1 MOD j2);
  if (j3 <> 1) or (j4 <> 0)then begin
    MessageDlg('SN incorrecto.', mtError, [mbOK], 0);
    Exit;
  end;


  MessageDlg('El programa se ha registrado correctamente.', mtInformation, [mbOK], 0);

end;

Es un ejemplo, pero fácilmente puedes generarlizarla un poco más... (lo he escrito sobre la macha y tampoco lo he pensado mucho...).
El número de serie no aparece completo, es más ni siquiera aparecen todos los trozos. Sinceramente creo que es casi imposible que alguien mirando la memoria del programa se le ocurre que 6 números que hay por ahí son parte del número de serie. Si la comprobación la cambias de orden pues mucho menos.

Otro tema es el del Debug; Eso si quieres lo dejamos para otro momento....
__________________
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.

Última edición por Neftali [Germán.Estévez] fecha: 28-03-2007 a las 19:09:12.
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.141
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Os agradezco a todos vuestro esfuerzo, de verdad. No doy pie con bola y no es culpa vuestra, ni mucho menos. No me encuentro muy bien, a lo que se ve. Supongo que será algo pasajero, puesto que no es la primera vez que me ocurre.

Probando la última solución propuesta por Seoane (no me gusta copiar y pegar, pero, he tenido que hacerlo sin remedio) encuentro el siguiente problema:

(Nótese que el nombre de la función "CheckSerial" es ahora "ComprobarNumeroSerie" pero que no cambia más que esto)

Código Delphi [-]
function TGeneradorSeriales.ComprobarNumeroSerie(numeroBase: integer;
 claveUsuario: string; numeroSerie: string): boolean;
var
  A: Integer;
begin
  Result:= FALSE;
  if (numeroBase <> 0) and (claveUsuario <> '') then
  begin
    A:= numeroBase * Length(claveUsuario) + Ord(claveUsuario[1]) * 666;
    Result:= GetNum(numeroSerie) = A;
    A := numeroBase * Ord(claveUsuario[1]) * 123;
    Result:= Result and (GetNum(numeroSerie) = A);
    A := numeroBase + (Length(claveUsuario) * Ord(claveUsuario[1])) * 6613;
    Result:= Result and (GetNum(numeroSerie) = A);
  end;

  if not Result then
  begin
    ShowMessage(Format('¿Número de serie incorrecto? %s', [numeroSerie]));
  end;

end;

El caso es que incluso proporcionando un código de serie válido este resulta ser "no válido". Por tanto entramos en el "If not Result then...".

He podido comprobar que si no proporcino clave de usuario y sí únicamente el número de serie, entro en el "if not Result then..." y el mensaje muestra efectivamente el número de serie introducido.

Pero si añado la clave de usuario (como tiene que ser) junto con el número de serie, entonces tampoco valida el número (aunque sea correcto) y además el mensaje muestra el número "partido"... no completo...

Esto me supera, probablemente. No he comprobado esto último que comenta Neftalí, puesto que lo acabo de leer. Y ya lo que me trae de cabeza es que intente buscar el número de serie en la memoria en antiguos programas en donde hacía uso del mismo sistema... y no aparezca.

O sea, que algo he tocado... y ya se sabe que lo que funciona no debe tocarse... ¡qué sé yo!

Bueno. Os agradezco a todos de veras el esfuerzo que ponéis en tratar de echarme una mano, pero, empiezo a pensar que debo tomarme esto mucho más seriamente de lo que soy capaz ahora mismo.

Tampoco corre prisa, supongo. Voy a tratar de tomármelo con más calma a ver qué tal...

Gracias a todos monstruos.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #6  
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
No entiendo:

Si yo genero un numero de serie con la función que aparece en el mensaje #40. Obtengo esto:
Código:
Base = 1234
Usuario = Domingo
Resultado = 53926-10321176-3149022
Y usando la función que te pase si, yo hago lo siguiente, obtengo TRUE:
Código Delphi [-]
CheckSerial(1234,'Domingo','53926-10321176-3149022');
Responder Con Cita
  #7  
Antiguo 28-03-2007
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.141
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Vale Seoane....

Sí; acabo de comprobar que funciona el asunto, y que el número de serie correcto no aparece en la memoria... ¡y esto quiere decir que lo he... que lo habéis conseguido! Toca ahora (para interesados) estudiar el código propuesto y saber porqué funciona y porqué antes no funcionaba...

En todo caso parece que el asunto está arreglado... en otro caso volveré a acosaros de nuevo. Gracias por todo. Si no fuera por vosotros probablemente esto me hubiera costado una úlcera (siempre quise decir algo así).

¡Muchas gracias!

PD. Cuando me asegure de que todo está en orden lo referiré de nuevo aquí, no podré evitarlo. Hasta pronto.

Por cierto... el código quedará más o menos de la siguiente forma:

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;

// Made in Seoane :P (ClubDelphi.com)
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 TGeneradorSeriales.ObtenerNumeroSerie
 (numeroBase: integer; claveUsuario: string): string;
var
  A: integer;
begin
  if (numeroBase <> 0) and (claveUsuario <> '') then
  begin
    A := numeroBase * Length(claveUsuario) + Ord(claveUsuario[1]) * 666;
    result := IntToStr(A) + '-';
    A := numeroBase * Ord(claveUsuario[1]) * 123;
    result := result + IntToStr(A) + '-';
    A := numeroBase + (Length(claveUsuario) * Ord(claveUsuario[1])) * 6613;
    result := result + IntToStr(A);
  end;
end;

function TGeneradorSeriales.ComprobarNumeroSerie(numeroBase: integer;
 claveUsuario: string; numeroSerie: string): boolean;
var
  A: integer;
begin
  result := false;
  if (numeroBase <> 0) and (claveUsuario <> '') then
  begin
    A := numeroBase * Length(claveUsuario) + Ord(claveUsuario[1]) * 666;
    result := GetNum(numeroSerie) = A;
    A := numeroBase * Ord(claveUsuario[1]) * 123;
    result := result and (GetNum(numeroSerie) = A);
    A := numeroBase + (Length(claveUsuario) * Ord(claveUsuario[1])) * 6613;
    result := result and (GetNum(numeroSerie) = A);
  end;
end;

end.
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 28-03-2007 a las 19:46:51.
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 08:06:28.


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