Autor Beitrag
2981611
Hält's aus hier
Beiträge: 10



BeitragVerfasst: So 13.02.11 16:00 
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.

home.netsurf.de/wolf...ardt/crchash_en.html

Dann habe ich folgenden code gerschrieben :

ausblenden 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.

www.webmaster-eye.de...hash-generieren.html

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

Lg :)
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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 ;-)

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.

Für diesen Beitrag haben gedankt: 2981611
2981611 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Mo 14.02.11 00:35 
Ich danke dir, habe meinen Fehler gefunden!

Cheers :)
Gammatester
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: 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
ausblenden 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
ausblenden 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.

Für diesen Beitrag haben gedankt: 2981611
2981611 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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 :

ausblenden 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 :

ausblenden 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 :

ausblenden 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 : 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 17.02.11 21:00 
@Key übergibt den Pointer zur Variable. Du willst aber @key[0] --> Den Zeiger auf's erste Element.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.

Für diesen Beitrag haben gedankt: 2981611
2981611 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Do 17.02.11 21:05 
Das hatte ich schon probiert - ich kriege das selbe Ergebnis.
Aber danke für den Vorschlag!
Gammatester
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: 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
ausblenden Quelltext
1:
2:
data DA76B0C1EEB1AB4D36D5F120B8B99345
key  000102030405060708090A0B0C0D0E0F
auch das gleiche Ergebnis wie Delphi:
ausblenden Quelltext
1:
HMAC-MD5: 629216063EE18946281A0CFF799F0DFD					

Für diesen Beitrag haben gedankt: 2981611
2981611 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Do 17.02.11 23:38 
Die referenz habe ich aus Microsofts Crypt API.

C# source :

ausblenden volle Höhe 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: 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

Für diesen Beitrag haben gedankt: 2981611
2981611 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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!