AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

DXE7+Indy: HMAC SHA256 - Encoding

Ein Thema von KaiW · begonnen am 16. Okt 2016 · letzter Beitrag vom 18. Okt 2016
Antwort Antwort
KaiW

Registriert seit: 5. Feb 2016
6 Beiträge
 
Delphi XE7 Architect
 
#1

DXE7+Indy: HMAC SHA256 - Encoding

  Alt 16. Okt 2016, 12:01
Hallo zusammen,

das eigentliche Kernproblem: Ich möchte die PHP-Funktionen hash_hmac und base64_encode in Delphi abbilden um das Datum '1234567890' mit dem Schlüssel 'ABCDEFG' zu signieren und das Ergebnis anschließend base64 kodieren.

In PHP sieht das ganze folgendermaßen aus:
Code:
echo base64_encode(hash_hmac('sha256', '1234567890', 'ABCDEFG', TRUE));
Ausgabe: aRGlc3RY1pKmKX0hvorkVKNcPigiJX2rksqXzlAeCLg=

Ich habe die Indy-Klasse TIdHMACSHA256 auserkoren, dies für mich zu tun:

Delphi-Quellcode:
uses
  IdHash, IdHashSHA, IdHMACSHA1, IdSSLOpenSSL, IdGlobal, IdCoderMIME;

function GenerateSignature(const AKey, AData: string): string;
var
   AHMAC: TIdBytes;
begin
     IdSSLOpenSSL.LoadOpenSSLLibrary;

     With TIdHMACSHA256.Create do
      try
         Key:= ToBytes(AKey, IndyTextEncoding_UTF16LE);
         AHMAC:= HashValue(ToBytes(AData, IndyTextEncoding_UTF16LE));
         Result:= TIdEncoderMIME.EncodeBytes(AHMAC);
      finally
         Free;
      end;
end;
Rückgabewert: H3eBWh0jKF0WZIK+NcYdwXRQAWrMrNLfOM3/mBU0XpU=

Auffällig ist, dass der Rückgabewert bei Memo.Lines.Text:= GenerateSignature('1234567890', 'ABCDEFG'); nicht mit dem über PHP ermittelten Wert übereinstimmt.
Meine Kernfrage lautet also: Warum ist das so und wie bekomme ich den gleichen Wert, den ich über die PHP-Funktionen erhalte?

Mein bisheriger Ansatz:
Ich vermute ein Problem mit den Zeichensätzen.
Ich habe verstanden, dass der Datentyp "string" bei Delphi XE7 dem Typ "UnicodeString" entspricht. UnicodeString arbeitet intern mit 2 Byte großen Zeichen (also 16bit) und ist UTF16 kodiert. http://docwiki.embarcadero.com/RADSt...Types_(Delphi).

Die Indy-Funktion "ToBytes" erwartet einen UnicodeString, sowie eine Zeichensatzangabe. Wird keine angegeben, wird ASCII verwendet, was ja zu Datenverlust führen könnte/wird. Also gebe ich UTF16 an. Da bei UTF16 zwischen BE (Big-Endian) und LE(Little-Endian) gewählt werden muss, habe ich mich für UTF16LE entschieden, da einerseits in einigen Artikeln im Netz LE als von "aktuellen Maschinen" verwendet bezeichnet wurde und andererseits Delphi's eigene Encodings "Unicode" und "BigEndianUnicode" heißen, was impliziert, dass Unicode (also LE) der Standard ist. Ich hatte hier auch bereits mit anderen Zeichensätzen experimentiert, jedoch ohne Erfolg.

Da TIdEncoderMIME.EncodeBytes(AHMAC); bei Übergabe der IdBytes als Parameter zunächst alles in einen Stream schreibt und diesen dann mit Charset 8bit wieder ausliest, vermute ich hier ebenfalls eine Fehlerquelle. Daher habe ich stattdessen auch

Delphi-Quellcode:
Result:= BytesToString(AHMAC, IndyTextEncoding_UTF16LE);
Result:= TIdEncoderMIME.EncodeString(Result, IndyTextEncoding_UTF16LE);
probiert. Leider ebenfalls ohne Erfolg.

Für jedwede Hilfe bin ich dankbar.

Kai
  Mit Zitat antworten Zitat
KaiW

Registriert seit: 5. Feb 2016
6 Beiträge
 
Delphi XE7 Architect
 
#2

AW: DXE7+Indy: HMAC SHA256 - Encoding

  Alt 18. Okt 2016, 12:09
Hallo,

hier die Lösung für alle, die ein ähnliches Problem haben:

Delphi-Quellcode:
function GenerateSignature(const AData, AKey: string): string;
var
   AHMAC: TIdBytes;
begin
     IdSSLOpenSSL.LoadOpenSSLLibrary;

     IF NOT TIdHashSHA256.IsAvailable
      THEN Raise Exception.Create('SHA-256 hashing is not available!');

     With TIdHMACSHA256.Create do
      try
         Key:= IndyTextEncoding_UTF8.GetBytes(AKey);
         AHMAC:= HashValue(IndyTextEncoding_UTF8.GetBytes(AData));
      finally
         Free;
      end;

     Result:= TIdEncoderMIME.EncodeBytes(AHMAC);
end;
Es muß also definitiv UTF8 verwendet werden, um ein gleiches Ergebnis zu erzielen.

Für weitere Informationen zum Thema Amazon MWS Signatur mit Delphi und Indy, siehe auch den folgenden Thread in Englisch:
http://stackoverflow.com/questions/4...d-indy-classes
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz