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í