2010-01-04 31 views
6

Ho bisogno di generare firme HMAC-SHA256 per l'API dei servizi web di Amazon. La vecchia libreria DCPcrypt ha le routine sha256 ma non esegue la firma HMAC. Qualcuno sa di una libreria di hashing gratuita che potrei usare?HMAC-SHA256 in Delphi

risposta

4

Dopo un po 'più di ricerca ho trovato OpenStreamSec - che sembra essere stato abbandonato alcuni anni fa, ma ancora compilato in D2007.

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

Generazione di un HMAC-256 per Amazon è davvero semplice:

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

Ho ottenuto questo lavoro, ma ho trovato bisogno di troncare alcuni caratteri per ottenere una firma appropriata. Ad esempio, ecco una firma che ottengo: "t1mYmkG73To5eyukq1lbDrBYGPcAAAAAAAAAAAAAAAAA =". Ma in realtà è senza la "A": t1mYmkG73To5eyukq1lbDrBYGPc =. C'è un ambiente che ho bisogno di cambiare? Se cambio il parametro "32" che non sembra cambiare le cose. –

2

Avete esaminato le risposte a this SO question?

+0

ho dato un'occhiata e non riesco a trovare alcuna attuazione HMAC nelle librerie libere. – Jacob

2

HMAC è solo una funzione che utilizza SHA256 per calcolare un hash secondo alcune regole definite. Se guardi allo Wikipedia ha un esempio pseudocode.

È anche possibile chiamare in .NET HMAC Class in System.Security.Cryptography tramite interfaccia COM.

3

La mia risposta preferita - Vorrei usare le librerie OpenSSL, la funzione HMAC. Ho usato con successo le librerie OpenSSL a Delfi, adottando e adattando il lavoro di M Ferrante http://www.disi.unige.it/person/FerranteM/delphiopenssl/
Per altre OpenSSL firma ecc vedere this link
In D2010 è qualcosa di simile (libeay32 è l'unità presa dal sito web e un po ' modificati per 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:\windows\paint.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; 

Poi lo chiamano con una frase chiave e stringa di dati. Il risultato è un TByte che può essere convertito come richiesto, ad es. In Base64 usando qualcosa come JclMime o una semplice funzione di tipo HexToString.
Per la versione precedente di Delphi dovrai fare un po 'di modifica dei PByte a PChar o qualcosa di simile.
Disclaimer: Non ho dati di riferimento per testare questo ma sembra funzionare bene!

0

Per quanto riguarda la risposta da Jacob: OpenStrSecII è una branca della StreamSec Tools 2.1, che viene venduto sotto un no-commerciale licenza senza senso e oggi (8 febbraio 2012) ha il supporto per Delphi Win32 fino a Delphi XE2 incluso. StreamSec Tools 4.0 supporta anche Win64.

2

navi Delfi con Indy installato e Indy ha una classe TIdHMACSHA256:

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('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;