2010-07-06 6 views
12

Ich bin in ein interessantes Problem geraten .. Es scheint, dass ComputeHash() für einen "HMACSHA256" Hash nicht deterministisch verhält .. wenn ich zwei Instanzen von HashAlgorithm mit HashAlgorithm.Create ("HMACSHA256") erstellen .. Und run ComputeHash, ich erhalte zwei verschiedene Ergebnisse. Unten ist eine statische Beispielklasse, die dieses Verhalten zeigt.Warum verhält sich ComputeHash nicht deterministisch?

internal static string HashPassword(byte[] bAll) 
{ 
    using (HashAlgorithm s = HashAlgorithm.Create("HMACSHA256")) 
    { 
     return Convert.ToBase64String(s.ComputeHash(bAll)); 
    } 
} 

habe ich auch versucht, den Anruf nicht statisch zu machen (es begann eigentlich nicht statisch, und ich habe doppelt und dreifach und quadrudruple überprüfte meine Eingabe-Array .. seine absolut die bei jedem Aufruf gleichen .. Ich habe auch Sachen im immidiate Fenster gemacht wie:

Convert.ToBase64String(HashAlgorithm.Create("HMACSHA256").ComputeHash(bAll) 

Und das bei dem Verfahren über einen Haltepunkt zweimal im immidiates Fenster läuft, gibt zwei unterschiedliche Hashes ..

ich weiß Hash ist wohl deterministisch zu sein. Was gibt es? Läuft etwas in einem Debugger? Oder irgendwelche anderen Ideen? wirklich dieses Recht jetzt Worte nur zwei seltsam ist :-P ..

Dank Josh

+3

Haben Sie kurze Beispieldaten, die dieses Problem aufweisen? Ändert sich "bAlle" zwischen oder während der Anrufe? –

+4

HMAC ist ein verschlüsselter Hash.Ich sehe den Schlüssel in Ihrem Beispielcode nicht. Ich glaube, dass der Schlüssel zufällig gesetzt wird, wenn Sie keinen explizit angeben. – dtb

+0

nichts ändert sich zwischen den Anrufen .. Wie ich schon sagte, ich habe es sogar aus dem Fenster "Immidiates" gemacht. Hier sind 4 Aufrufe von meinem Immidiates-Fenster .. ja, sie sind nicht perfekt, weil Sie den HashAlgorithm entsorgen sollten, aber die Ergebnisse sind die Gleiches über Immidiates-Fenster oder die Methode. (Ich werde sie in den nächsten Kommentar einschließen, becase, ich habe keinen Platz zum Kopieren hier einfügen) –

Antwort

24

HMAC ist ein verschlüsselter Hash. Ich sehe den Schlüssel in Ihrem Beispielcode nicht.

HashAlgorithm.Create("HMACSHA256") erstellt eine HashAlgorithm-Instanz, sodass sie nichts über einen Schlüssel weiß. Wahrscheinlich nur Anrufe this HMACSHA256 Constructor:

public HMACSHA256()

Initialisiert eine neue Instanz der HMACSHA256-Klasse mit einem zufällig Schlüssel erzeugt.

Sie wollen this constructor:

public HMACSHA256(byte[] key)

Initialisiert eine neue Instanz der HMACSHA256 Klasse mit den Schlüsseldaten angegeben.

Wenn Sie den HMAC-Algorithmus zu hartcodieren möchten, können Sie KeyedHashAlgorithm.Create verwenden und einen bestimmten Schlüssel liefern, indem die KeyedHashAlgorithm.Key Eigenschaft festlegen.

Wenn Sie keinen Schlüssel verwenden möchten, verwenden Sie einen nicht verschlüsselten Hash wie SHA256.

+0

Seine beste Wette ist die Verwendung von ['KeyedHashAlgorithm.Create'] (http://msdn.microsoft.com/en-us/library/s5zz2x4d.aspx). Lektion gelernt: Kenne deine Hashes! – Randolpho

+0

Ich werde in den Provider-Kram einsteigen und herausfinden, warum MS einen Hash-Hashwert verwendet/verwendet, aber HashAlgorithm.Create() verwendet, wenn es darauf ankommt. es kann sein, dass ich 2.0 basierte ASP.NET Provider Starter Pack-Quelle mit 4.0 Framework verwende .. Anyways, danke, dass Sie mich in die richtige Richtung weisen. –

+0

@Josh: Es gibt ein paar Orte, wo MS "überraschende" Zufälligkeit hatte. Einige CypherMode-Einstellungen für die Verschlüsselung verwenden beispielsweise einen zufälligen Initialisierungsvektor, wenn Sie dies nicht angeben. Der spaßige Teil ist, wenn Ihre Verschlüsselung und Entschlüsselung perfekt für alle außer den ersten 8 Bytes Ihrer Daten funktioniert. Ich denke, sie haben hier eine gute Entscheidung getroffen. Ich möchte lieber, dass ein Programm schnell ausfällt, weil ich die Sicherheitsparameter, die es benötigt, nicht verstehe, als es standardmäßig auf einen "funktionierenden", aber weniger sicheren Zustand eingestellt ist. – Brian

3

Sie benötigen einen Schlüssel für HMACSHA256. Der Schlüssel wird zufällig sein, wenn er nicht an den Konstruktor übergeben wird.

5

Hinzufügen nur dazu in der Hoffnung, jemand die Kopfschmerzen zu retten, die ich durchgemacht habe.

Im Fall von .Net Mitgliedschaft Provider, stellen Sie sicher, dass Sie die Einstellung in Ihrer web.config oder app.config haben. Sonst wird es automatisch seinen eigenen Schlüssel erzeugen ... bei der Authentifizierung und dann am Ende kriegerisch lachen.