Bueno me he leido todo el hilo, yo programo en Lazarus, y hace unos años realicé esta solución, es algo muy parecido a lo que han dicho por aqui, solo les paso la función que utilicé para realizar la digestion completa tanto en md5 o sha1 y pasarla a base64, parametro msg la cadena orginal, tipo es para indicar el tipo de digestion MD5 o SHA1, la llave esta en formato DER:
Código Delphi
[-]
function TFinterfaz.sello(msg,tipo: widestring): string;
var
Len: cardinal;
mdctx: EVP_MD_CTX;
inbuf, outbuf: array [0..4095] of char;
key: puEVP_PKEY;
bp: pBIO;
pk: PuRSA;
rkey: PuRSA;
i: integer;
s: string;
Function EncodeBase64(S : String) : String;
Var
S1,S2 : TStringStream;
begin
S1:=TStringStream.Create(S);
Try
S1.Position:=0;
S2:=TStringStream.Create('');
Try
With TBase64EncodingStream.Create(S2) do
Try
CopyFrom(S1,S1.Size);
Finally
Free;
end;
Result:=S2.DataString;
finally
S2.Free;
end;
finally
S1.Free;
end;
end;
function TipoError: string;
var
ErrMsg: array [0..160] of char;
begin
ERR_error_string(ERR_get_error, @ErrMsg);
result := StrPas(@ErrMsg);
end;
begin
OpenSSL_add_all_algorithms;
OpenSSL_add_all_ciphers;
OpenSSL_add_all_digests;
ERR_load_crypto_strings;
bp := BIO_new(BIO_s_file());
BIO_read_filename(bp, Pchar(ruta+nomarchivo));
pk := nil;
rkey := PEM_read_bio_RSAPrivateKey(bp, pk, nil, PChar(passw));
if rkey = nil then
raise Exception.Create('Error en llave privada.' + TipoError);
key := EVP_PKEY_new;
EVP_PKEY_assign(key, EVP_PKEY_RSA, rkey);
StrPCopy(inbuf, msg);
if tipo = 'MD5' then
EVP_SignInit(@mdctx, EVP_md5());
if tipo = 'SHA1' then
EVP_SignInit(@mdctx, EVP_sha1());
EVP_SignUpdate(@mdctx, @inbuf, StrLen(inbuf));
EVP_SignFinal(@mdctx, @outbuf, Len, key);
EVP_cleanup;
s:='';
for i:=0 to len-1 do
s:=s+outbuf[i];
result:=EncodeBase64(S)
end;
espero que a alguien le sirva como a mi