En este ejemplo, para que se entienda bien, porque de eso tratan los ejemplos, cargaremos la llave en una variable. También cabe destacar que los nombres de variables y funciones que se ven en este ejemplo, son para aprender, en la práctica hay que esconder los datos, no usar para cifrar una función llamada cifrar, etc. También hay que validar datos y utilizar try al leer y escribir archivos.
Veamos el código:
unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, BlowFish; type { TForm1 } TForm1 = class(TForm) BGuardar: TButton; BLeer: TButton; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; Edit5: TEdit; Edit6: TEdit; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; procedure BGuardarClick(Sender: TObject); procedure BLeerClick(Sender: TObject); procedure FormCreate(Sender: TObject); private function Cifrar (const texto:String):RawByteString; function DesCifrar (const texto:String):RawByteString; { private declarations } public { public declarations } end; type TRegistro=Record Servidor:String[100]; Usuario:String[100]; Clave:String[100]; end; var Form1: TForm1; archivo:String; llave:String; implementation {$R *.lfm} { TForm1 } procedure TForm1.FormCreate(Sender: TObject); begin archivo:=GetCurrentDir+PathDelim+'prueba.dat'; llave:='La llave'; end; function TForm1.Cifrar(const texto: String): RawByteString; var str_Cifrar:TBlowFishEncryptStream; streamTexto:TStringStream; begin streamTexto:=TStringStream.Create(''); str_Cifrar:=TBlowFishEncryptStream.Create(llave,streamTexto); str_Cifrar.WriteAnsiString(texto); str_Cifrar.Free; Result:=streamTexto.DataString; streamTexto.Free; end; function TForm1.DesCifrar(const texto: String): RawByteString; var str_DesCifrar:TBlowFishDeCryptStream; unstream:TStringStream; temp:RawByteString; begin unstream:=TStringStream.Create(texto); unstream.Position:=0; str_DesCifrar:=TBlowFishDeCryptStream.Create(llave,unstream); temp:=str_DesCifrar.ReadAnsiString; str_DesCifrar.Free; unstream.Free; Result:=temp; end; procedure TForm1.BGuardarClick(Sender: TObject); var Registro:TRegistro; FReg:File of TRegistro; begin Registro.Servidor:=Cifrar(Edit1.text); Registro.Usuario:=Cifrar(Edit2.text); Registro.Clave:=Cifrar(Edit3.text); AssignFile(FReg,archivo); Rewrite(FReg); Write(FReg,Registro); CloseFile(FReg); end; procedure TForm1.BLeerClick(Sender: TObject); var Registro:TRegistro; FReg:File of TRegistro; begin AssignFile(FReg,archivo); Reset(FReg); Read(FReg,Registro); CloseFile(FReg); edit4.Text:=DesCifrar(Registro.Servidor); edit5.Text:=DesCifrar(Registro.Usuario); Edit6.Text:=DesCifrar(Registro.Clave); end; end.
Lo primero que debemos hacer es incluir la unidad BlowFish en uses.
Si trabajamos con archivos binarios, definimos un registro para guardar y leer los datos.
En el método Create simplemente definimos el archivo y la llave, que como ven, puede contener espacios.
Luego 2 funciones para encriptar y desencriptar y 2 procedimientos para guardar y leer, para un ejemplo, alcanza y sobra.
Veamos la función Cifrar:
function TForm1.Cifrar(const texto: String): RawByteString; var str_Cifrar:TBlowFishEncryptStream; streamTexto:TStringStream; begin streamTexto:=TStringStream.Create(''); str_Cifrar:=TBlowFishEncryptStream.Create(llave,streamTexto); str_Cifrar.WriteAnsiString(texto); str_Cifrar.Free; Result:=streamTexto.DataString; streamTexto.Free; end;
Nótese que no devuelve un string, sino un RawByteString que es una cadena de caracteres (string) sin ningún CodePage asociado, ideal e indispensable para que esto funcione.
Necesitamos dos variables, una para el stream de cifrado de Blow Fish y otro un stream común, donde volcaremos el texto cifrado.
Creamos el stream común (streamTexto) vacío.
Creamos el stream de cifrado de BF y le pasamos como parámetros la llave (establecida en FormCreate) y el stream de texto vacío. Es importante hacer todo en este orden.
Ahora ciframos con WriteAnsiString, como parámetro le pasamos la constante de la función llamada texto.
Liberamos el stream de cifrado, el texto cifrado está en el stream de texto (streamtexto).
Finalmente asignamos al resultado de la función el DataString del stream de texto y liberamos el mismo.
Ahora la función DesCifrar:
function TForm1.DesCifrar(const texto: String): RawByteString; var str_DesCifrar:TBlowFishDeCryptStream; unstream:TStringStream; temp:RawByteString; begin unstream:=TStringStream.Create(texto); unstream.Position:=0; str_DesCifrar:=TBlowFishDeCryptStream.Create(llave,unstream); temp:=str_DesCifrar.ReadAnsiString; str_DesCifrar.Free; unstream.Free; Result:=temp; end;
También usamos dos variables para los streams y una tercera del tipo RawByteString que contendrá el valor que retornará la función. Podría obviarse esta variable supuestamente, pero por algo está ahí, la verdad no me acuerdo, algún error me habrá hecho intentar con una variable temporal, funcionó y ahí está.
Aquí cuando creamos el stream de texto, no lo hacemos vacío sino con el valor de la constante texto y a su vez, volvemos a cero su posición para que BF la lea desde el comienzo.
Creamos el stream de descifrado de BF y le pasamos también la llave y el stream de texto.
Ahora sí desciframos usando el método ReadAnsiString perteciente a TBlowFishDeCryptStream y lo asignamos a la variable temp; liberamos los streams y como resultado enviamos el valor de temp.
El resto del código no lo voy a explicar porque simplemente es usar estas dos funciones, escribir y leer el archivo binario de la manera habitual.
Descargar el código fuente: BlowFish.7z
o en GitLab
No hay comentarios:
Publicar un comentario