Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create OAuth Signature with HMAC-SHA1 Encryption returns HTTP 401

The Question
I need to authenticate to an API which needs OAuth encryption.

I'm in the right direction but I am sure something is wrong with my signature base string. Since the HMACSHA1 Hash is based on a Key and BaseString, I get a wrong oauth_signature.

OAuth Signing Process

So far
I have been able to collect all the required pieces of data, which includes:

  • Consumer Key
  • Consumer Secret
  • Acces Token
  • Acces Secret
  • Sha1Hased Value (Based on Key and Message, where Message is the signature Base string)
  • Signature Base String

The Problem
I get a HTTP(401 Bad Request) returned because of a invalid signature.

note: I'm pretty sure it is how I build my Signature Base String. For info about the API Docs I used, please check bottom page.

The Code

GetOAuthToken (Doing the actual request)

public static string GetAuthorizationToken()
{
    string TimeInSecondsSince1970 = ((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds).ToString();
    string Nonce = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(TimeInSecondsSince1970
    + TimeInSecondsSince1970 + TimeInSecondsSince1970));
    HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(GetAppleApiUrl.GetUrl(AppleApiUrl.SESSION_TOKEN));
    httpWebRequest.Method = "GET";

    string consumer_secret = Uri.EscapeDataString(Settings.SettingsManager.consumer_secret);
    string token_secret = Uri.EscapeDataString(Settings.SettingsManager.access_secret);

    string signature_base_string = GetSignatureBaseString(TimeInSecondsSince1970, Nonce);
    string SHA1HASH = GetSha1Hash(consumer_secret + "&" + token_secret, signature_base_string);
                
    string Header =
       "OAuth realm=" + '"' + "ADM" + '"' + "," +
       "oauth_consumer_key=" + '"' + Settings.SettingsManager.consumer_key + '"' + "," +
       "oauth_token=" + '"' + Settings.SettingsManager.access_token + '"' + "," +
       "oauth_signature_method=" + '"' + "HMAC-SHA1" + '"' + "," +
       "oauth_signature= " + '"' + SHA1HASH + '"' + "," + 
       "oauth_timestamp=" + '"' + TimeInSecondsSince1970 + '"' + "," +
       "oauth_nonce=" + '"' + Nonce + '"' + "," +
       "oauth_version=" + '"' + "1.0" + '"' + ",";
   
    httpWebRequest.Headers.Add(HttpRequestHeader.Authorization, Header);
    var Result = httpWebRequest.GetResponse();

    return Result.ToString();
}

GetSha1Hash

public static string GetSha1Hash(string key, string message)
{
    var encoding = new System.Text.ASCIIEncoding();

    byte[] keyBytes = encoding.GetBytes(key);
    byte[] messageBytes = encoding.GetBytes(message);

    string Sha1Result = string.Empty;

    using (HMACSHA1 SHA1 = new HMACSHA1(keyBytes))
    {
        var Hashed = SHA1.ComputeHash(messageBytes);
        Sha1Result = Convert.ToBase64String(Hashed);
    }

    return Sha1Result;
}

GetSignatureBaseString

public static string GetSignatureBaseString(string TimeStamp, string Nonce)
{
    //1.Convert the HTTP Method to uppercase and set the output string equal to this value.
    string Signature_Base_String = "Get";
    Signature_Base_String = Signature_Base_String.ToUpper();

    //2.Append the ‘&’ character to the output string.
    Signature_Base_String = Signature_Base_String + "&";

    //3.Percent encode the URL and append it to the output string.
    string PercentEncodedURL = Uri.EscapeDataString(GetAppleApiUrl.GetUrl(AppleApiUrl.SESSION_TOKEN));
    Signature_Base_String = Signature_Base_String + PercentEncodedURL;

    //4.Append the ‘&’ character to the output string.
    Signature_Base_String = Signature_Base_String + "&";

    //5.append parameter string to the output string.
    Signature_Base_String = Signature_Base_String + Uri.EscapeDataString("oauth_consumer_key=" + Settings.SettingsManager.consumer_key);
    Signature_Base_String = Signature_Base_String + Uri.EscapeDataString("&oauth_token=" + Settings.SettingsManager.access_token);
    Signature_Base_String = Signature_Base_String + Uri.EscapeDataString("&oauth_signature_method=" +"HMAC-SHA1");
    Signature_Base_String = Signature_Base_String + Uri.EscapeDataString("&oauth_timestamp=" + TimeStamp);
    Signature_Base_String = Signature_Base_String + Uri.EscapeDataString("&oauth_nonce=" + Nonce);
    Signature_Base_String = Signature_Base_String + Uri.EscapeDataString("&oauth_version=" + "1.0");

    return Signature_Base_String;
}

Result (Fiddler) Fiddler Result

API Doc enter image description here

like image 398
Nick Prozee Avatar asked Jun 08 '15 09:06

Nick Prozee


1 Answers

It looks like you should sort parameters alphabetically in Header string and within GetSignatureBaseString method as described in this comment and Twitter OAuth documentation

like image 178
Leonid Vasilev Avatar answered Sep 24 '22 07:09

Leonid Vasilev