Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTP MAC Authentication using C#

I'm trying to create a client for the new tent.io protocol that's being developed and they are using the HTTP MAC Oauth2 scheme described by https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-http-mac-01.

I've written a simple method in C# that creates the Authorization header, but when I submit my request I get a simple "Invalid MAC signature" error.

Since I don't have a reference implementation, I'm struggling to figure out what's wrong with my code. I'm posting it here in the hope that somebody can spot my mistake.

public string GetAuthorizationHeader(string macKeyIdentifier, string macKey, string macAlgorithm, string method, Uri uri)
{
    TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
    string timestamp = ((int)t.TotalSeconds).ToString();

    string nonce = new Random().Next().ToString();

    string normalizedString = string.Format("{0}\n{1}\n{2}\n{3}\n{4}\n{5}\n\n", 
                                            timestamp, 
                                            nonce, 
                                            method,
                                            uri.PathAndQuery, 
                                            uri.Host, 
                                            uri.Port);

    HashAlgorithm hashGenerator = null;
    if (macAlgorithm == "hmac-sha-256")
    {
        hashGenerator = new HMACSHA256(Encoding.ASCII.GetBytes(macKey));
    }
    else if (macAlgorithm == "hmac-sha-1")
    {
        hashGenerator = new HMACSHA1(Encoding.ASCII.GetBytes(macKey));
    }
    else
    {
        throw new InvalidOperationException("Unsupported MAC algorithm");
    }

    string hash = System.Convert.ToBase64String(hashGenerator.ComputeHash(Encoding.ASCII.GetBytes(normalizedString)));

    StringBuilder authorizationHeader = new StringBuilder();
    authorizationHeader.AppendFormat(@"id=""{0}"",ts=""{1}"",nonce=""{2}"",mac=""{3}""",
                                     macKeyIdentifier, timestamp, nonce, hash);

    return authorizationHeader.ToString();
}

I create the full header using the returned value and it looks something lke this

Authorization: MAC id="a:dfsdfa2",ts="1349277638",nonce="1469030797",mac="ibZ/HXaoz2VgBer3CK7K9vu0po3K+E36K+TQ9Sgcw6o="

I'm sure I'm missing something small, but I cannot see it.

Any help would be very much appreciated!

like image 951
Tomas McGuinness Avatar asked Oct 03 '12 16:10

Tomas McGuinness


1 Answers

It turns out the code above is perfect, but I was passing the wrong HTTP method value into it!

Where I was getting the error, I was POST'ing JSON, but I had actually put "GET" into the GetAuthorizationMethod!

Once I'd corrected that, I got an access_token value from Tent.is.

like image 109
Tomas McGuinness Avatar answered Oct 19 '22 21:10

Tomas McGuinness