Cifrar y descifrar en Base64

La siguiente unit permite codificar y descodificar un conjunto de bytes utilizando la codificacion Base64. Utiliza las librerias criptograficas de la api de windows, lo que nos permite obtener un codigo muy simple y facil de entender.

(base64.pas)

unit base64;
 
interface
 
uses Windows, SysUtils, Classes;
 
function BinToStr(Binary: PByte; Len: Cardinal): String;
procedure StrToStream(Str: String; Stream: TStream);
 
implementation
 
const
  CRYPT_STRING_BASE64 = 1;
 
function CryptBinaryToString(pbBinary: PByte; cbBinary: DWORD; dwFlags: DWORD;
  pszString: PChar; var pcchString: DWORD): BOOL; stdcall;
  external 'Crypt32.dll' name 'CryptBinaryToStringA';
 
function CryptStringToBinary(pszString: PChar; cchString: DWORD; dwFlags: DWORD;
  pbBinary: PByte; var pcbBinary: DWORD; pdwSkip: PDWORD;
  pdwFlags: PDWORD): BOOL; stdcall;
  external 'Crypt32.dll' name 'CryptStringToBinaryA';
 
function BinToStr(Binary: PByte; Len: Cardinal): String;
var
  Count: DWORD;
begin
  Count:= 0;
  if CryptBinaryToString(Binary,Len,CRYPT_STRING_BASE64,nil,Count) then
  begin
    SetLength(Result,Count);
    if not CryptBinaryToString(Binary,Len,CRYPT_STRING_BASE64,PChar(Result),
      Count) then
      Result:= EmptyStr;
  end;
end;
 
procedure StrToStream(Str: String; Stream: TStream);
var
  Buffer: PByte;
  Count: DWORD;
begin
  Count:= 0;
  if CryptStringToBinary(PChar(Str),Length(Str),CRYPT_STRING_BASE64,nil,Count,
    nil,nil) then
  begin
    GetMem(Buffer,Count);
    try
      if CryptStringToBinary(PChar(Str),Length(Str),CRYPT_STRING_BASE64,Buffer,
        Count,nil,nil) then
        Stream.WriteBuffer(Buffer^,Count);
    finally
      FreeMem(Buffer);
    end;
  end;
end;
 
end.

Para codificar un archivo:

var
  Stream: TMemoryStream;
  Texto: String;
 
begin
  Stream:= TMemoryStream.Create;
  try
    Stream.LoadFromFile('imagen.jpg');
    Texto:= BinToStr(Stream.Memory,Stream.Size);
  finally
    Stream.Free;
  end;
end.

Para descodificarlo:

var
 Stream: TFileStream;
 
begin
  Stream:= TFileStream.Create('imagen.jpg',fmCreate);
  try
    StrToStream(Texto,Stream);
  finally
    Stream.Free;
   end;
end.

Un compañero del clubdelphi

Un compañero del clubdelphi (kanvictor) me ha avisado de que la función CryptBinaryToString solo esta disponible a partir de WindowsXP. Habrá que tenerlo en cuenta si se pretende usar esta función en Windows 2000 o 98.

tengo clientes con Windows

tengo clientes con Windows 2000 o 98, hay alguna version de la función CryptBinaryToString para utilizarla, o que recomiendas.

Al parecer, sustituyendo esa

Al parecer, sustituyendo esa librería por una versión mas actual ya funciona. Ahora la conveniencia de hacer ese cambio ya dejo que lo decidas tu, por otro lado puede ser suficiente copiar una versión mas actual de la librería Crypt32.dll a la misma carpeta de nuestro ejecutable.

Hola yo trabajo con windows

Hola yo trabajo con windows 2000 y en efecto sustituyendo el crypt32.dll que utiliza XP funciona perfectamente, en mi caso sustitui la version que trae windows 2000 por la version de windows XP 5.131.2600.5512, este archivo lo sustitui en la carpeta de C:\WINNT\system32, pero hay que sustituirlo iniciando windows a modo seguro solo simbolos del sistema, para que lo deje copiar, primero se debe remplazar el archivo que trae por defecto y luego sustituirlo con el de XP. Espero les ayude a los que todavia tienen que usar windows 2000.

Efectivamente, incorporando

Efectivamente, incorporando la dll a la carpeta de trabajo del ejecutable funciona bien.

Buenas, el codigo que tienes

Buenas, el codigo que tienes en el ejemplo para descodificar el archivo es correcto ? Gracias.

Pues creo que si, ¿has

Pues creo que si, ¿has tenido algún problema para utilizarlo?

Una consulta lei el foro de

Una consulta lei el foro de club de delphi y ahi comentabas que tu codigo no usa librerias externas , peor la crypto32.dll seria una externa en el codigo de Aes tenes lo siguinte que hace referencia a crypto32.dll

function CryptBinaryToString(pbBinary: PByte; cbBinary: DWORD; dwFlags: DWORD;
  pszString: PChar; var pcchString: DWORD): BOOL; stdcall;
  external 'Crypt32.dll' name 'CryptBinaryToStringA';

Ahora mismo no se a que post

Ahora mismo no se a que post del foro te refieres, pero supongo que cuando lo dije me refería a la librería de AES, que efectivamente no usa ninguna librería externa y además puede compilar tanto en delphi como en freepascal, en sus versiones para linux y windows. (Un ejemplo con freepascal para linux)

Pero volviendo al código de este post, la función CryptBinaryToString es una API del sistema, forma parte del propio windows, no se hasta que punto se la puede considerar externa.

Enviar un comentario nuevo

El contenido de este campo se mantiene privado y no se mostrará públicamente.