2
votes

All of this is new to me so please forgive my noobish question.

I'm trying to figure out HMAC step by step.

Let's say I have a following SHA-1 method:

public static string SHA_1(string input) 
{
    SHA1CryptoServiceProvider mySha = new SHA1CryptoServiceProvider();
    string temp = BitConverter.ToString(mySha.ComputeHash(Encoding.UTF8.GetBytes(input)));
    temp = temp.Replace("-", "").ToUpper();
    return temp;
} 

It receives a plain text string;

Let's say my secret key is "" (empty string) and so is the message; The HMAC is supposed to be: fbdb1d1b18aa6c08324b7d64b71fb76370690e1d

Now that's where I am a bit lost. I'll write down the steps as I understand them and please correct me if I am wrong (or where I am wrong rather).

  1. If the key is shorter than 64 bytes I need to pad it with 0's. So the padded key is 0x00 (x64 - because the key is empty, otherwise it's 64-key.Length);
  2. Two constants each 64 bytes long are:

ipad = 0x36 (x64)

opad = 0x5c (x64)

  1. because the key is empty string XOR results in the same opad and ipad, i.e.

ipad XOR key = ipad

opad XOR key = opad

  1. At this point all left to do is to compute the HMAC itself.

So: HMAC = Hash(opad || Hash(ipad || message)) and that should be it.

But I am not sure how to execute this. The message is a text string. opad and ipad are uint/byte arrays. I can convert them to ASCII as well and receive respectively:

ipad_str = "6666666666..." x64

opad_str = "\\\\\\\...." x64

Now my HMAC is supposed to be:

HMAC = SHA_1("\\\\\\...."+ SHA_1("6666666...."))

but the result doesn't match. Instead it is: 4DCF4B8D646EBD77EB704A9240BFA429078131A2

What am I missing here? Does the empty message have to be padded as well? I suspect that I misinterpret the concatenation, but I am not sure what other options I have. Should I leave ipad and opad as hex? SHA1 methods receives string so I must convert to some sort of a string, I just can't figure out what type exactly.

Any help would be greatly appreciated. Thanks in advance and Happy New Year!

1
.NET has HMAC built in, you should use it.Cory Nelson
I know it does. I am trying to understand the process, because I need to implement a custom HMAC for school project.JNeverTells
Have you studied rfc2104?zaph
Usually you convert message string to bytes using a Encoding.UTF8.GetBytes(message); Also let's be clear that you understand the peusdocode ipad || message indicates concatenating/appending these, not OR/XOR: upload.wikimedia.org/wikipedia/commons/7/7f/SHAhmac.svgAaronLS
Also, if you've implemented your own SHA_1, then check your intermediate results against known working SHA1 hash. For example, once you append ipad || message, use a builtin C# sha1 hash to verify that your SHA_1() and C#'s both produce the same result from that given input. At least then you narrow the possible problem areas.AaronLS

1 Answers

2
votes

The problem with my method was so obvious, it's not even funny. While appending the result of the opad and inner hash I left the inner hash in hex format but treated it as ASCII, as a result 104 bytes were sent to the outer hash instead of 84. So the solution is something like: HMAC = SHA_1(opad + HexToASCII(SHA_1(ipad)));