Saltar al contenido

HMAC-SHA256 en Delfos

este problema se puede abordar de variadas formas, por lo tanto te enseñamos la resolución más completa en nuestra opinión.

Solución:

Delphi se envía con Indy instalado, e Indy tiene un TIdHMACSHA256 clase:

uses
  IdGlobal, IdHashSHA, IdHMAC, IdHMACSHA1, IdSSLOpenSSL;

function CalculateHMACSHA256(const value, salt: String): String;
var
  hmac: TIdHMACSHA256;
  hash: TIdBytes;
begin
  LoadOpenSSLLibrary;
  if not TIdHashSHA256.IsAvailable then
    raise Exception.Create('SHA256 hashing is not available!');
  hmac := TIdHMACSHA256.Create;
  try
    hmac.Key := IndyTextEncoding_UTF8.GetBytes(salt);
    hash := hmac.HashValue(IndyTextEncoding_UTF8.GetBytes(value));
    Result := ToHex(hash);
  finally
    hmac.Free;
  end;
end;

Después de buscar un poco más, encontré OpenStreamSec, que parece que fue abandonado hace unos años pero aún se compila en D2007.

http://sourceforge.net/projects/openstrsecii/

Generar un HMAC-256 para Amazon es realmente sencillo:

StrToMime64(HMACString(haSHA256, SecretKey, 32, DataToHash));

Mi respuesta favorita: usaría las bibliotecas OpenSSL, la función HMAC. He utilizado con éxito las bibliotecas OpenSSL en Delphi adoptando y adaptando el trabajo de M Ferrante http://www.disi.unige.it/person/FerranteM/delphiopenssl/
Para otras firmas de OpenSSL, etc., consulte este enlace

En D2010 es algo como esto (libeay32 es la unidad tomada del sitio web y ligeramente modificada para Unicode/D2010):

uses libeay32;

const
  LIBEAY_DLL_NAME = 'libeay32.dll';
  EVP_MAX_MD_SIZE = 64;

function EVP_sha256: pEVP_MD; cdecl; external LIBEAY_DLL_NAME;
function HMAC(evp: pEVP_MD; key: PByte; key_len: integer; 
              data: PByte; data_len: integer; 
              md: PByte; var md_len: integer): PByte; cdecl; external LIBEAY_DLL_NAME;

function GetHMAC(const AKey, AData: string): TBytes;
var
  key, data: TBytes;
  md_len: integer;
  res: PByte;
begin
  OpenSSL_add_all_algorithms;
  // Seed the pseudo-random number generator
  // This should be something a little more "random"!
  RAND_load_file('c:windowspaint.exe', 512);

  key := TEncoding.UTF8.GetBytes(AKey);
  data := TEncoding.UTF8.GetBytes(AData);
  md_len := EVP_MAX_MD_SIZE;
  SetLength(result, md_len);
  res := HMAC(EVP_sha256, @key[0], Length(key), @data[0], Length(data), @result[0], md_len);
  if (res <> nil) then
  begin
    SetLength(result, md_len);
  end;
end;

Entonces llámalo con un key frase y datos string. El resultado es un TBytes que se puede convertir según sea necesario, por ejemplo, a Base64 usando algo como JclMime o una función simple de tipo HexToString.
Para una versión anterior de Delphi, tendrá que cambiar un poco de PBytes a PChars o algo similar.
Descargo de responsabilidad: no tengo datos de referencia para probar esto, ¡pero parece funcionar bien!

Reseñas y puntuaciones

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *