2010-01-04 14 views
6

Ich muss HMAC-SHA256-Signaturen für die Amazon Web Services API generieren. Die alte DCPcrypt-Bibliothek hat sha256-Routinen, führt jedoch keine HMAC-Signierung durch. Wer weiß von einer kostenlosen Hash-Bibliothek, die ich verwenden könnte?HMAC-SHA256 in Delphi

Antwort

4

Nach ein wenig mehr Suche fand ich OpenStreamSec - was aussieht, als wäre es vor ein paar Jahren aufgegeben worden, aber kompiliert immer noch in D2007.

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

einen HMAC-256 für Amazon zu erzeugen ist wirklich einfach:

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

Ich habe diese Arbeit, aber finde ich muss einige Zeichen abgeschnitten, um eine richtige Signatur zu bekommen. Zum Beispiel, hier ist eine Signatur, die ich bekomme: "t1mYmkG73To5eyukq1lbDrBYGPcAAAAAAAAAAAAAAAA =". Aber es ist tatsächlich, dass ohne das "A": t1mYmkG73To5eyukq1lbDrBYGPc =. Gibt es eine Einstellung, die ich ändern muss? Wenn ich den "32" -Parameter ändere, scheint das Dinge nicht zu ändern. –

2

Haben Sie bei den Antworten auf this SO question? sah

+0

ich einen Blick hatte und ich jede Implementierung von HMACs in den freien Bibliotheken nicht finden kann. – Jacob

2

HMAC ist nur eine Funktion, die SHA256 einen Hash nach einigen definierten Regeln zur Berechnung verwendet. Wenn Sie Wikipedia betrachten, hat es ein pseudocode Beispiel.

Sie könnten auch in .NET's HMAC Class in System.Security.Cryptography über COM interrop aufrufen.

3

Meine Lieblingsantwort - Ich würde die OpenSSL-Bibliotheken verwenden, die HMAC-Funktion. Ich habe erfolgreich verwendet die OpenSSL-Bibliotheken in Delphi durch die Annahme und Arbeit von M Ferrante Anpassung http://www.disi.unige.it/person/FerranteM/delphiopenssl/
Für andere OpenSSL Unterzeichnung etc sehen this link
In D2010 ist es so etwas wie dieses (libeay32 das Gerät von der Website genommen und leicht modifiziert für 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; 

es dann rufen sie mit einem Schlüssel Satz und Datenstring. Das Ergebnis ist eine TByte, die nach Bedarf in Base64 konvertiert werden kann, indem man etwas wie JclMime oder eine einfache HexToString-Funktion verwendet.
Für ältere Version von Delphi müssen Sie ein bisschen PBytes zu PChars oder etwas Ähnlichem ändern.
Haftungsausschluss: Ich habe keine Referenzdaten, um dies zu testen, aber es scheint zu funktionieren ok!

0

Im Hinblick auf die Antwort von Jacob: OpenStrSecII ist ein Zweig der StreamSec Tools 2.1, die unter einer kommerziellen no- verkauft wird Nonsense-Lizenz und heute (8. Februar 2012) unterstützt Delphi Win32 bis einschließlich Delphi XE2. StreamSec Tools 4.0 unterstützt auch Win64.

2

Delphi Schiffe mit Indy installiert und Indy hat eine TIdHMACSHA256 Klasse:

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;