2016-04-12 2 views
4

J'ai besoin de calculer le HMAC en utilisant la fonction de hachage SHA256. J'ai une clé secrète encodée au format base64. Il existe également un outil en ligne qui calcule correctement le HMAC (vérifié). http://www.freeformatter.com/hmac-generator.html j'ai écrit l'extrait de code suivant:Calcul de hachage HMAC SHA256 en 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); 
} 

PROBLÈME: Mon code ne génère pas le bon HMAC. J'ai vérifié différentes étapes en utilisant différents outils en ligne et d'autres implémentations C#. Seule la conversion de base64 n'est pas confirmée. Qu'est-ce que je rate?

MISE À JOUR: signatureHashHex Calculé par mon code est « a40e0477a02de1d134a5c55e4befa55d6fca8e29e0aa0a0d8acf7a4370208efc »

RÉPONSE: La question a été causée par une documentation trompeuse indiquant la clé est fournie en base64. Voir la réponse acceptée:

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

Etes-vous sûr que la signature est encodée en UTF8? –

+0

Avez-vous essayé ceci: http://stackoverflow.com/q/33419006/479156 – Ivar

+0

Non, mais j'ai essayé un certain nombre de codages différents avec le même résultat. – Kalitsov

Répondre

5

Votre résultat est correct, la différence est que l'outil que vous lien vers ne pas decode base64 pour la valeur de clé et la traite comme une série de personnages.

E.g. Pour dupliquer son résultat traiter votre clé comme une chaîne:

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

qui donne

559bd871bfd21ab76ad44513ed5d65774f9954d3232ab68dab1806163f806447 

(Ceci est évidemment pas la bonne façon de le faire)

+0

Vous vous demandez pourquoi 'GetBytes (...)' est "manifestement faux"? Que faire si ma phrase clé est «This_is_my_secret_keyphrase» '? – derpirscher

+0

Parce qu'une chaîne Base64 est une série codée d'octets et ses octets (après décodage) qui doivent être utilisés, pas la chaîne elle-même. Vous ne commandez pas une nouvelle chaise, alors asseyez-vous sur la boîte. ("This_is_my_secret_keyphrase" n'est pas Base64) –

+1

Une chaîne simple est aussi une série codée d'octets. C'est juste une question d'interprétation.Le format du mot de passe stocké est totalement non pertinent, à condition qu'il puisse être converti en vecteur d'octet correct utilisé pour le chiffrement/déchiffrement. Quelle est la différence entre 'Convert.FromBase64String (" VGhpc19pc19teV9zZNNyZXRfa2V5cGhyYXNl ")' et 'System.Text.Encoding.UTF8.GetBytes (" This_is_my_secret_keyphrase ")'? Il suffit de s'assurer que les deux côtés utilisent la même méthode sur la même entrée. Je ne me souviens pas d'une exigence pour que la clé soit une chaîne base64. – derpirscher

0

HMAC: Il est code d'authentification de message.Il est utilisé pour vérifier l'intégrité des données de l'expéditeur et il est un algorithme forward.It fonctionne sur la clé secrète partagée qui est connue par l'expéditeur et le récepteur à la fois.Avant de générer la valeur de hachage, nous devons encoder la clé et le message. nous pouvons utiliser l'un des codages UTF8 ou ASCIIEncoding.

UTF8 encodage:

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); 

Maintenant, nous pouvons utiliser ce message codé et clé dans le code ci-dessus.