Entwickler-Ecke

Internet / Netzwerk - HMAC MD5 Problem


2981611 - So 13.02.11 16:00
Titel: HMAC MD5 Problem
Hallo leute,

Ich habe seit mehreren Tagen ein problem : Ich möchte esinen HMAC hash erstellen, und zwar mit MD5.

Ich habe dazu von Wolfgang Erhardt die Hash package runtergeladen.

http://home.netsurf.de/wolfgang.ehrhardt/crchash_en.html

Dann habe ich folgenden code gerschrieben :


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
function HMACMD5(Text, key: ansistring): ansistring;
var
   ctx: THMAC_Context;
   mac: TMD5Digest;
begin
  hmac_MD5_init(ctx, @key[1], length(key));
  hmac_MD5_update(ctx, @Text[1], length(Text));
  hmac_MD5_final(ctx , mac);
  Result := HexStr(@mac, sizeof(mac));
end;


Dieser gibt mir auch einen Hash zurück, alles kein Problem. Nur das er nicht stimmt.

http://www.webmaster-eye.de/hmac-md5-hash-generieren.html

Diese Seite generiert mir einen komplett anderen, und ich weiss nicht warum. Habt ihr eine Idee?

Lg :)


BenBE - Mo 14.02.11 00:01

Das Schöne an Standards ist, dass man sie Verifizieren kann:

Schau mal in den Appendix unten auf Seite 8 und Seite 9: Da sind mehrere Testvektoren, die Du einfach mal ausprobieren solltest. Die Webseite erzeugt die korrekten HMACs für die Testvektoren. Scheint also ein Fehler in deiner Unit zu sein, bzw. in der Art, wie due die verwendest. Im Zweifelsfalle einfach mal parallel zum RFC debuggen ;-)


2981611 - Mo 14.02.11 00:35

Ich danke dir, habe meinen Fehler gefunden!

Cheers :)


Gammatester - Mo 14.02.11 10:21

user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
Das Schöne an Standards ist, dass man sie Verifizieren kann:

Schau mal in den Appendix unten auf Seite 8 und Seite 9: Da sind mehrere Testvektoren, die Du einfach mal ausprobieren solltest. Die Webseite erzeugt die korrekten HMACs für die Testvektoren. Scheint also ein Fehler in deiner Unit zu sein, bzw. in der Art, wie due die verwendest. Im Zweifelsfalle einfach mal parallel zum RFC debuggen ;-)

Wie kommst Du darauf daß die Webseite die korrekten HMACS erzeugt? Mal abgesehen davon, daß keiner weiß, was ein HMAC-Seed sein soll. Nehmen wir mal an, es ist der Schlüssel. Für den den Testvektor

Quelltext
1:
2:
3:
4:
5:
key =         0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
key_len =     16 bytes
data =        "Hi There"
data_len =    8  bytes
digest =      0x9294727a3638bb1c13f48ef8158bfc9d
erhalte ich dann als Ausgabe

Quelltext
1:
2:
3:
4:
Der generierte HMAC MD5 Hash für "Hi There" lautet:
1dee2143f7a90714f2afee7adafa3d140b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b

Der benutzte Seed lautet: 0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
Das ist noch nicht einmal ein sinnvolles Format, geschweige denn ein richtiger erster Teile. Im Testprogramm t_hmac.pas des Archivs wird jedoch u.a. genau dieser Testvektor richtig verarbeitet.


2981611 - Do 17.02.11 20:02

Ich muss noch einmal nerven glaube ich - mein problem ist doch nicht ganz weg.

Wenn ich ein String übergebe klappt es wunderbar - Ich möchte jedoch sowohl MD5 als auch Key als array of bytes übergeben.
Da die funktionen Pointer benutzen, dachte ich es wäre kein problem.

Hier mein Code :


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
Procedure HMACMD5(Data: Array of byte; Key: Array of byte); 
var
  ctx: THMAC_Context;
  mac: TMD5Digest;
begin
  hmac_MD5_init(ctx, @Key, Length(key));
  hmac_MD5_update(ctx, @Data,Length(Data));
  hmac_MD5_final(ctx, mac);
  Authpacket.Hash[0] := mac[0]; //kopieren des hashes in mein struct
  Authpacket.Hash[1] := mac[1];
  Authpacket.Hash[2] := mac[2];
  Authpacket.Hash[3] := mac[3];
  Authpacket.Hash[4] := mac[4];
  Authpacket.Hash[5] := mac[5];
  Authpacket.Hash[6] := mac[6];
  Authpacket.Hash[7] := mac[7];
  Authpacket.Hash[8] := mac[8];
  Authpacket.Hash[9] := mac[9];
  Authpacket.Hash[10] := mac[10];
  Authpacket.Hash[11] := mac[11];
  Authpacket.Hash[12] := mac[12];
  Authpacket.Hash[13] := mac[13];
  Authpacket.Hash[14] := mac[14];
  Authpacket.Hash[15] := mac[15];
end;


Ja ich weiss, das mit dem kopieren könnte man auch schöner lösen, aber ich möchte Fehler ausschliessen.

Hier die Arrays die ich übergebe :

Key :


Delphi-Quelltext
1:
Key : array [0 .. 15of byte = ($00$01$02$03$04$05$06$07$08$09$0A$0B$0C$0D$0E$0F);                    


Hash :


Delphi-Quelltext
1:
Hash : Array [0..15of byte = (21811817619323817717177542132413218418514769); // Dezimal                    


Als HMAC bekomme ich :

Decimal : 98, 146, 22, 6, 62, 225, 137, 70, 40, 26, 12, 255, 121, 159, 13, 253
Hex : 62, 92, 16, 06, 3E, E1, 89, 46, 28, 1A, 0C, FF, 79, 9F, 0D, FD

Dies ist falsch. Weiss jemand warum? Ich benutze die HMAC_MD5 unit von Wolfgang Ehrhardt (Könnt ihr hier finden : http://pastebin.com/0aTqZeeS)

Edit :
Der hash wäre richtig : 57 B6 68 77 9E 9E C4 DA C5 63 84 0F F1 45 63 46

Danke für eure Hilfe!


BenBE - Do 17.02.11 21:00

@Key übergibt den Pointer zur Variable. Du willst aber @key[0] --> Den Zeiger auf's erste Element.


2981611 - Do 17.02.11 21:05

Das hatte ich schon probiert - ich kriege das selbe Ergebnis.
Aber danke für den Vorschlag!


Gammatester - Do 17.02.11 23:28

Ich weiß nicht wo Du den Sollwert her hast. Die Units und Dein Code sind OK. Jedenfalls liefert zB CryptoBench/Crypto++ für

Quelltext
1:
2:
data DA76B0C1EEB1AB4D36D5F120B8B99345
key  000102030405060708090A0B0C0D0E0F
auch das gleiche Ergebnis wie Delphi:

Quelltext
1:
HMAC-MD5: 629216063EE18946281A0CFF799F0DFD                    


2981611 - Do 17.02.11 23:38

Die referenz habe ich aus Microsofts Crypt API.

C# source :


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;






namespace ConsoleApplication1
{
    class Program
    {
        static string MakeString(byte[] byteArray)
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte b in byteArray) sb.AppendFormat("{0:X2} ", b);
            return sb.ToString();
        }



        static void Main(string[] args)
        {
            {
    string login = "mylogin";
    string password = "password";
    byte[] key1 = new byte[] { 0123456789101112131415 };
    Console.WriteLine(String.Format("Login: {0}", login));
    Console.WriteLine(String.Format("Password: {0}", password));
    Console.WriteLine(String.Format("Key: {0}", MakeString(key1)));
    Console.WriteLine();
    byte[] loginBytes = Encoding.ASCII.GetBytes(login);
    byte[] passwordBytes = Encoding.ASCII.GetBytes(password);
    Console.WriteLine(String.Format("Login Bytes: {0}", MakeString(loginBytes)));
    Console.WriteLine(String.Format("Password Bytes: {0}", MakeString(passwordBytes)));
    Console.WriteLine();
    MD5 md5 = MD5.Create();
    byte[] loginWithPasswordBytes = loginBytes.Concat<byte>(passwordBytes).ToArray<byte>();
    Console.WriteLine(string.Format("Contacted Bytes: {0}", MakeString(loginWithPasswordBytes)));
    Console.WriteLine();
    byte[] mhash = md5.ComputeHash(loginWithPasswordBytes);
    Console.WriteLine(string.Format("MD5 Hash: {0}", MakeString(mhash)));
    byte[] hash = new HMACMD5(mhash).ComputeHash(key1);
    Console.WriteLine(string.Format("Hash: {0}", MakeString(hash)));
    Console.ReadKey();
}


    
        }
    }
}


Dieser code generiert mir einen HMAC hash in der form wie ich ihn brauche - gibt es vielleicht versionsunterschiede?


Gammatester - Fr 18.02.11 00:52

Ich sehe immer noch nicht das Problem, wo Du den HMAC-Sollstring her hast: MD5(concat("mylogin","password"))
= MD5("myloginpassword") = DA76B0C1EEB1AB4D36D5F120B8B99345

Womit wir wieder in der Ausgangssituation wären: HMAC mit data = DA76B0C1EEB1AB4D36D5F120B8B99345 und key = 000102030405060708090A0B0C0D0E0F lieferr das Ergebnis 629216063EE18946281A0CFF799F0DFD.

Edit: Jetzt hab ich's wohl. Dein Microsofts Crypt API code vertauscht offensichtlich key und data!!
HMAC(key=DA76B0C1EEB1AB4D36D5F120B8B99345, data=000102030405060708090A0B0C0D0E0F) = 57B668779E9EC4DAC563840FF1456346


2981611 - Fr 18.02.11 01:00

Ach du meine Güte.

Danke dafür, da wäre ich jetzt nicht drauf gekommen. Du hast mir grad wochen arbeit abgenommen :)

Danke!