Create OAuth Signature with HMAC-SHA1 Encryption returns HTTP 401

14,035

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

Share:
14,035
Nick Prozee
Author by

Nick Prozee

He coded the code

Updated on June 05, 2022

Comments

  • Nick Prozee
    Nick Prozee almost 2 years

    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

  • Nick Prozee
    Nick Prozee almost 9 years
    I can award it in 22 Hours.