Ya he tratado anteriormente este tema pero parece que son necesarios unos cuantos ejemplos mas, sobre todo a la hora de trabajar con ficheros, ya que hasta ahora la mayoría de los ejemplos que he puesto trabajan con cadenas de texto.
El siguiente ejemplo muestra dos funciones, una para cifrar y otra para descifrar:
uses AES, SHA256; procedure CifrarArchivo(Origen,Destino: String; Clave: AnsiString); var Src, Dst: TFileStream; Key: TAESKey; ExpandedKey: TAESExpandedKey; Size: int64; begin Src:= TFileStream.Create(Origen,fmOpenRead or fmShareDenyNone); try Dst:= TFileStream.Create(Destino,fmCreate); try // Guardamos el tamaño del fichero original Size:= Src.Size; Dst.WriteBuffer(Size,Sizeof(Size)); // Usamos como Key el hash SHA256 de la Clave TSHA256HASH(Key):= CalcSHA256(Clave); AEsExpandKey(ExpandedKey,Key); // Ciframos el archivo AESEncryptStreamECB(Src,Dst,ExpandedKey); finally Dst.Free; end; finally Src.Free; end; end; procedure DescifrarArchivo(Origen,Destino: String; Clave: AnsiString); var Src, Dst: TFileStream; Key: TAESKey; ExpandedKey: TAESExpandedKey; Size: int64; begin Src:= TFileStream.Create(Origen,fmOpenRead); try Dst:= TFileStream.Create(Destino,fmCreate); try // Leemos el tamaño del fichero Src.ReadBuffer(Size,Sizeof(Size)); // Usamos como Key el hash SHA256 de la Clave TSHA256HASH(Key):= CalcSHA256(Clave); AEsExpandKey(ExpandedKey,Key); // Desciframos el archivo AESDecryptStreamECB(Src,Dst,ExpandedKey); // Lo recortamos a su tamaño original Dst.Size:= Size; finally Dst.Free; end; finally Src.Free; end; end; // Por ejemplo CifrarArchivo(ParamStr(0),ParamStr(0)+'.1','Password'); DesCifrarArchivo(ParamStr(0)+'.1',ParamStr(0)+'.2','Password');
Le podemos dar una vuelta de tuerca comprimiendo el fichero cifrado:
uses AES, SHA256, zlib; procedure zCifrarArchivo(Origen,Destino: String; Clave: AnsiString); var Src, Dst: TFileStream; Cmp: TCompressionStream; Key: TAESKey; ExpandedKey: TAESExpandedKey; Size: int64; begin Src:= TFileStream.Create(Origen,fmOpenRead or fmShareDenyNone); try Dst:= TFileStream.Create(Destino,fmCreate); try // Guardamos el tamaño del fichero original Size:= Src.Size; Dst.WriteBuffer(Size,Sizeof(Size)); // Usamos como Key el hash SHA256 de la Clave TSHA256HASH(Key):= CalcSHA256(Clave); AEsExpandKey(ExpandedKey,Key); // Ciframos el archivo y comprimimos el resultado Cmp:= TCompressionStream.Create(clMax,Dst); try AESEncryptStreamECB(Src,Cmp,ExpandedKey); finally Cmp.Free; end; finally Dst.Free; end; finally Src.Free; end; end; procedure zDescifrarArchivo(Origen,Destino: String; Clave: AnsiString); var Src, Dst: TFileStream; Cmp: TDeCompressionStream; Key: TAESKey; ExpandedKey: TAESExpandedKey; Size: int64; begin Src:= TFileStream.Create(Origen,fmOpenRead); try Dst:= TFileStream.Create(Destino,fmCreate); try // Leemos el tamaño del fichero Src.ReadBuffer(Size,Sizeof(Size)); // Usamos como Key el hash SHA256 de la Clave TSHA256HASH(Key):= CalcSHA256(Clave); AEsExpandKey(ExpandedKey,Key); // Descomprimimos y desciframos el archivo Cmp:= TDeCompressionStream.Create(Src); try AESDecryptStreamECB(Cmp,Dst,ExpandedKey); Dst.Size:= Size; finally Cmp.Free; end; finally Dst.Free; end; finally Src.Free; end; end; // Por ejemplo zCifrarArchivo(ParamStr(0),ParamStr(0)+'.1','Password'); zDesCifrarArchivo(ParamStr(0)+'.1',ParamStr(0)+'.2','Password');
Podemos hacer un ejemplo mas general, si en vez de archivos usamos streams
procedure CifrarStream(Src, Dst: TStream; Clave: AnsiString); var Key: TAESKey; ExpandedKey: TAESExpandedKey; Size: int64; begin // Guardamos el tamaño del stream original Size:= Src.Size; Dst.WriteBuffer(Size,Sizeof(Size)); // Usamos como Key el hash SHA256 de la Clave TSHA256HASH(Key):= CalcSHA256(Clave); AEsExpandKey(ExpandedKey,Key); // Ciframos el stream AESEncryptStreamECB(Src,Dst,ExpandedKey); end; procedure DescifrarStream(Src, Dst: TStream; Clave: AnsiString); var Key: TAESKey; ExpandedKey: TAESExpandedKey; Size: int64; begin // Leemos el tamaño del stream original Src.ReadBuffer(Size,Sizeof(Size)); // Usamos como Key el hash SHA256 de la Clave TSHA256HASH(Key):= CalcSHA256(Clave); AEsExpandKey(ExpandedKey,Key); // Descomprimimos el stream AESDecryptStreamECB(Src,Dst,ExpandedKey); Dst.Size:= Size; end; // Por ejemplo var F1,F2: TFileStream; M: TMemorystream; begin F1:= TFileStream.Create(ParamStr(0),fmOpenRead or fmShareDenyNone); try M:= TMemoryStream.Create; try // Ciframos el contenido del primer stream y // guardamos el resultado en el segundo stream CifrarStream(F1,M,'Password'); // Ponemos el stream cifrado en la posicion 0 M.Position:= 0; // Y lo desciframos F2:= TFileStream.Create(ParamStr(0)+'.1',fmCreate); try DescifrarStream(M,F2,'Password'); finally F2.Free; end; finally M.Free; end; finally F1.Free; end; end; // O este otro ejemplo var M1, M2: TMemorystream; begin M1:= TMemoryStream.Create; try M2:= TMemoryStream.Create; try Memo1.Lines.SaveToStream(M1); // Ponemos el stream en la posicion 0 M1.Position:= 0; CifrarStream(M1,M2,'Password'); // Ponemos el stream cifrado en la posicion 0 M2.Position:= 0; // Borramos M1 M1.Clear; // Y lo desciframos DescifrarStream(M2,M1,'Password'); M1.Position:= 0; Memo2.Lines.LoadFromStream(M1); finally M2.Free; end; finally M1.Free; end; end;
Enlaces de interes:
Cifrado AES-256 - http://delphi.jmrds.com/?q=node/31
Calcular el hash SHA256 de un texto - http://delphi.jmrds.com/?q=node/64
Comentarios
casimiro (no verificado)
Sáb, 27/08/2011 - 12:58
Enlace permanente
Estupendo, ¡gracias! :)
Estupendo, ¡gracias! :)
Antonio (no verificado)
Lun, 29/08/2011 - 17:37
Enlace permanente
Funciona Perfecto. Eres un
Funciona Perfecto. Eres un genio.
Un millón de gracias y otro tanto de saludos.
Añadir nuevo comentario