2016-04-12 9 views
4

Ich muss die HMAC mithilfe der Hash-Funktion SHA256 berechnen. Ich habe einen geheimen Schlüssel im Base64-Format codiert. Außerdem gibt es ein Online-Tool, das den HMAC (verifiziert) korrekt berechnet. http://www.freeformatter.com/hmac-generator.html Ich schrieb den folgenden Code-Schnipsel:HMAC SHA256 Hash-Berechnung in C#

var signatureHashHexExpected = "559bd871bfd21ab76ad44513ed5d65774f9954d3232ab68dab1806163f806447"; 
var signature = "123456:some-string:2016-04-12T12:44:16Z"; 
var key = "AgQGCAoMDhASFAIEBggKDA4QEhQCBAYICgwOEBIUAgQ="; 

var shaKeyBytes = Convert.FromBase64String(key); 
using (var shaAlgorithm = new System.Security.Cryptography.HMACSHA256(shaKeyBytes)) 
{ 
    var signatureBytes = System.Text.Encoding.UTF8.GetBytes(signature); 
    var signatureHashBytes = shaAlgorithm.ComputeHash(signatureBytes); 
    var signatureHashHex = string.Concat(Array.ConvertAll(signatureHashBytes, b => b.ToString("X2"))).ToLower(); 

    System.Diagnostics.Debug.Assert(signatureHashHex == signatureHashHexExpected); 
} 

PROBLEM: Mein Code die richtige HMAC nicht erzeugen. Ich verifizierte verschiedene Schritte mit verschiedenen Online-Tools und alternativen C# -Implementierungen. Nur die Konvertierung von base64 wird nicht bestätigt. Was vermisse ich?

UPDATE: Berechnet signatureHashHex durch meinen Code "a40e0477a02de1d134a5c55e4befa55d6fca8e29e0aa0a0d8acf7a4370208efc"

ANTWORT: das Problem durch eine irreführende Dokumentation verursacht wurde den Schlüssel unter Angabe wird in Base64-Format zur Verfügung gestellt. Siehe die akzeptierte Antwort:

var shaKeyBytes = System.Text.Encoding.UTF8.GetBytes(key); 
+0

Sind Sie sicher, dass die Signatur in UTF8 codiert ist? –

+0

Haben Sie das versucht: http://stackoverflow.com/q/33419006/479156 – Ivar

+0

Nein, aber ich habe versucht, eine Reihe von verschiedenen Codierungen mit dem gleichen Ergebnis. – Kalitsov

Antwort

5

Ihr Ergebnis richtig ist, ist der Unterschied, weil das Werkzeug, das Sie verknüpfen tut nicht dekodieren Base64 für den Schlüsselwert und behandelt sie als eine Reihe von Zeichen.

z. So duplizieren Sie das Ergebnis Ihren Schlüssel als String behandeln:

var shaKeyBytes = System.Text.Encoding.UTF8.GetBytes("AgQGCAoMDhASFAIEBggKDA4QEhQCBAYICgwOEBIUAgQ="); 

Welche

559bd871bfd21ab76ad44513ed5d65774f9954d3232ab68dab1806163f806447 

(Dies ist offensichtlich nicht der richtige Weg, es zu tun)

+0

Bither zu erklären, warum 'GetBytes (...)' "offensichtlich falsch" ist? Was ist, wenn mein Schlüsselsatz "This_is_my_secret_keyphrase" 'ist? – derpirscher

+0

Weil eine Base64-Zeichenkette eine codierte Reihe von Bytes ist und deren diese Bytes (nach der Decodierung) verwendet werden sollten, nicht die Zeichenkette selbst. Du bestellst keinen neuen Stuhl und sitzt dann einfach auf der Box. ('" This_is_my_secret_keyphrase "' ist nicht Base64) –

+1

Ein einfacher String ist auch eine codierte Reihe von Bytes. Es ist nur eine Frage der Interpretation.Das Format, in dem die Passphrase gespeichert wird, ist völlig irrelevant, solange es in den korrekten Byte-Vektor konvertiert werden kann, der für die Verschlüsselung/Entschlüsselung verwendet wird. Was ist der Unterschied zwischen 'Convert.FromBase64String (" VGhpc19pc19teV9zZWNyZXRfa2V5cGhyYXNl ") und' System.Text.Encoding.UTF8.GetBytes ("This_is_my_secret_keyphrase") '? Man muss nur sicherstellen, dass beide Seiten die gleiche Methode für die gleiche Eingabe verwenden. Ich erinnere mich nicht an eine Anforderung für den Schlüssel, um eine Base64-Zeichenfolge zu sein. – derpirscher

0

HMAC ergibt: Es ist ein Message Authentication Code.Es wird verwendet, um die Datenintegrität des Absenders zu verifizieren und es ist ein Forward-Only-Algorithmus. Es funktioniert auf den gemeinsamen geheimen Schlüssel, der von Absender und Empfänger bekannt ist. Vor dem Erzeugen von Hash-Wert müssen wir Schlüssel und Nachricht verschlüsseln. wir können entweder eine der Kodierungen UTF8 oder ASCIIEncoding verwenden.

UTF8-Codierung:

var signature = "123456:some-string:2016-04-12T12:44:16Z"; 
var key = "AgQGCAoMDhASFAIEBggKDA4QEhQCBAYICgwOEBIUAgQ="; 


var signatureBytes = System.Text.Encoding.UTF8.GetBytes(signature); 
var shaKeyBytes = System.Text.Encoding.UTF8.GetBytes(key); 

ASCIIEncoding Encoding:

var signature = "123456:some-string:2016-04-12T12:44:16Z"; 
var key = "AgQGCAoMDhASFAIEBggKDA4QEhQCBAYICgwOEBIUAgQ="; 

var signatureBytes = System.Text.ASCIIEncoding.GetBytes(signature); 
var shaKeyBytes = System.Text.ASCIIEncoding.GetBytes(key); 

Jetzt können wir diese codierte Nachricht und Schlüssel in dem obigen Code verwenden.