Ver Mensaje Individual
  #9  
Antiguo 31-08-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Reputación: 24
seoane Va por buen camino
Vamos a darle un poco de vida a este hilo

Imaginar que que queremos descifrar un archivo cifrado con ftpup desde linux.

Nada nos impide usar algo como esto:
Código:
wine ftpup (Parametros)
Funcionaría, pero por qué no crear una aplicación propia para linux. Vamos a utilizar el compilador freepascal y el siguiente código:
Código Delphi [-]
program cifrar;

uses
  SysUtils,
  Classes,
  AES in 'AES.pas';

type
  EGetOptError = class(Exception);

var
  Options: record
    Decrypt: Boolean;
    Dest: String;
    Key: String;
    Source: String;    
  end;

function Starts(Sub, Str: String): Boolean;
begin
  Result:= SameText(Sub,Copy(Str,1,Length(sub)));
end;

procedure Getopt;
var
  i,j: Integer;
  Str: String;
begin
  FillChar(Options,Sizeof(Options),#0);
  for i:= 1 to ParamCount do
  begin
    Str:= ParamStr(i);
    if (Copy(Str,1,2) = '--') and (Length(Str) > 2) then
    begin
      if SameText(Str,'--Decrypt') then
        Options.Decrypt:= TRUE
      else if Starts('--Key=',Str) then
      begin
        if Options.Key = EmptyStr then
          Options.Key:= Copy(Str,Length('--Key=') + 1,MAXINT)
        else
          raise EGetOptError.Create(Str);
      end else if Starts('--Source=',Str) then
      begin
        if Options.Source = EmptyStr then
          Options.Source:= Copy(Str,Length('--Source=') + 1,MAXINT)
        else
          raise EGetOptError.Create(Str);
      end else if Starts('--Dest=',Str) then
      begin
        if Options.Dest = EmptyStr then
          Options.Dest:= Copy(Str,Length('--Dest=') + 1,MAXINT)
        else
          raise EGetOptError.Create(Str);
      end;
    end else if (Copy(Str,1,1) = '-') and (Length(Str) > 1) then
    begin
      Str:= UpperCase(Str);
      for j:= 2 to Length(Str) do
      begin
        if Str[j] = 'D' then
          Options.Decrypt:= TRUE
        else
          raise EGetOptError.Create(Str);
      end;
    end else
    begin
      raise EGetOptError.Create(Str);
    end;
  end;
end;


procedure Run;
var
  AESKey: TAESKey;
  ExKey: TAESExpandedKey;
  Src, Dst: TStream;
  Size: int64;
  IV: TAESState;
begin
  FillChar(AESKey,Sizeof(AESKey),#0);
  if Length(Options.Key) > Sizeof(AESKey) then
    move(PChar(Options.Key)^,AESKey,Sizeof(AESKey))
  else
    move(PChar(Options.Key)^,AESKey,Length(Options.Key));
  AESExpandKey(ExKey,AESKey);
  FillChar(IV,Sizeof(IV),#0);  
  Src:= TFileStream.Create(Options.Source,fmOpenRead or fmShareDenyNone);
  try
    Dst:= TFileStream.Create(Options.Dest,fmCreate); 
    try 
      if Options.Decrypt then
      begin
        if Src.Read(Size,Sizeof(Size)) = Sizeof(Size) then
        begin
          AESDecryptStreamCBC(IV,Src,Dst,ExKey);
          if (Size > 0) and (Src.Size > Size) then
            Dst.Size:= Size;
        end;
      end else
      begin
        Size:= Src.Size;
        Dst.Write(Size,Sizeof(Size));
        AESEncryptStreamCBC(IV,Src,Dst,ExKey);
      end;
    finally
      Dst.Free;
    end;
  finally
    Src.Free;
  end;
end;

procedure Help;
begin
  Writeln;
  Writeln('Uso: cifrar [opciones]');
  Writeln('  --decrypt -d');
  Writeln('    Descifrar (Cifrar es la opcion por defecto)');
  Writeln('  --key');
  Writeln('    Clave de cifrado, hasta 32 caracteres.');
  Writeln('  --source');
  Writeln('    Archivo de origen');
  Writeln('  --dest');
  Writeln('    Archivo de destino.');  
  Writeln;
  Writeln('Ejemplos:');
  Writeln('  cifrar --key=clave --source=archivo.txt --dest=archivo.bin');
  Writeln('  cifrar -d --key=clave --source=archivo.txt --dest=archivo.bin');
  Writeln;      
end;


begin
  try
    if ParamCount > 0 then
    begin
      GetOpt;
      Run;
    end else
      Help;
  except
    On E: EGetOptError do
    begin
      Writeln('Error en el parametro: ',E.Message);
      Help;
    end;
    On E: Exception do
      Writeln(E.Message);
  end;
end.
Y lo compilamos de la siguiente manera:
Código:
fpc -Sd cifrar.pas
El programa resultante permite cifrar y descifrar un archivo utilizando AES 256, siguiendo el mismo formato que el programa ftpup.

Por ejemplo, así cifra:
Código:
./cifrar --source=archivo.txt --dest=archivo.bin --key=clave
Y así descifra:
Código:
./cifrar -d --source=archivo.bin --dest=archivo.txt --key=clave
PD: La unit AES.pas la puedes conseguir aquí

Última edición por seoane fecha: 31-08-2007 a las 15:26:06.
Responder Con Cita