在C#中生成OAuth1签名

5

我有一个大问题。我正在使用C#开发UWP Windows 10应用程序,希望使用OAuth 1。

一切几乎都没问题,但签名错误。不过,在Microsoft GitHub上找到了示例代码。显然,我做了一些修改...

我的代码:

private async Task GoCo()
{
        String LifeInvaderUrl = "http://stage.api.lolilolz.be/v8/login";

        string timeStamp = GetTimeStamp();
        string nonce = GetNonce();
        string consumerKey = "noob-stage";
        string consumerSecret = "TOPSECRETxxXXxx";

        string SigBaseStringParams = "oauth_consumer_key=" + consumerKey;
        SigBaseStringParams += "&" + "oauth_signature_method=HMAC-SHA1";
        SigBaseStringParams += "&" + "oauth_timestamp=" + timeStamp;
        SigBaseStringParams += "&" + "oauth_nonce=" + nonce;
        SigBaseStringParams += "&" + "oauth_version=1.0";

        string SigBaseString = "POST&";
        SigBaseString += Uri.EscapeDataString(LifeInvaderUrl) + "&" + Uri.EscapeDataString(SigBaseStringParams);

        String Signature = GetSignature(SigBaseString, consumerSecret);

        string authorizationHeaderParams = "oauth_consumer_key=\"" + consumerKey + "\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"" + timeStamp + "\", oauth_nonce=\"" + nonce +   "\", oauth_vesrion=\"1.0\", oauth_signature=\"" + Uri.EscapeDataString(Signature)+ "\"";

        HttpClient httpClient = new HttpClient();

        //...

}

并且签名生成器方法:

string GetSignature(string sigBaseString, string consumerSecretKey)
{
        IBuffer KeyMaterial = CryptographicBuffer.ConvertStringToBinary(consumerSecretKey + "&", BinaryStringEncoding.Utf8);
        MacAlgorithmProvider HmacSha1Provider = MacAlgorithmProvider.OpenAlgorithm("HMAC_SHA1");
        CryptographicKey MacKey = HmacSha1Provider.CreateKey(KeyMaterial);
        IBuffer DataToBeSigned = CryptographicBuffer.ConvertStringToBinary(sigBaseString, BinaryStringEncoding.Utf8);
        IBuffer SignatureBuffer = CryptographicEngine.Sign(MacKey, DataToBeSigned);
        string Signature = CryptographicBuffer.EncodeToBase64String(SignatureBuffer);

        return Signature;
}

提前感谢你 :)


遇到了同样的问题,我的签名一直失败... - Denny
3个回答

5

您的基本字符串参数顺序不正确。对于OAuth 1.0,它需要被排序。我创建了一个通用函数来创建基本字符串,您可以使用它。

`        private static string GetSignatureBaseString(string strUrl, string TimeStamp,
            string Nonce, string strConsumer, string strOauthToken, SortedDictionary<string, string> data)
        {
            //1.Convert the HTTP Method to uppercase and set the output string equal to this value.
            string Signature_Base_String = "POST";
            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(strUrl);
            Signature_Base_String = Signature_Base_String + PercentEncodedURL;

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

            //5.append OAuth parameter string to the output string.
            var parameters = new SortedDictionary<string, string>
            {
                {"oauth_consumer_key", strConsumer},
                { "oauth_token", strOauthToken },
                {"oauth_signature_method", "HMAC-SHA1"},
                {"oauth_timestamp", TimeStamp},
                {"oauth_nonce", Nonce},
                {"oauth_version", "1.0"}
            };

            //6.append parameter string to the output string.
            foreach (KeyValuePair<string, string> elt in data)
            {
                parameters.Add(elt.Key, elt.Value);
            }

            bool first = true;
            foreach (KeyValuePair<string, string> elt in parameters)
            {
                if (first)
                {
                    Signature_Base_String = Signature_Base_String + Uri.EscapeDataString(elt.Key + "=" + elt.Value);
                    first = false;
                }
                else
                {
                    Signature_Base_String = Signature_Base_String + Uri.EscapeDataString("&" + elt.Key + "=" + elt.Value);
                }
            }

            return Signature_Base_String;
        }

使用上述函数,您将得到一个基础字符串,您可以将其与您的秘钥一起传递给以下函数,以获得签名。
private static string GetSha1Hash(string key, string base)
    {
        var encoding = new System.Text.ASCIIEncoding();

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

        string strSignature = string.Empty;

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

        return strSignature;
    }

在 GetSha1Hash 函数中应该使用什么密钥? - Naner
关键字应该以 $"{consumerSecret}&{tokenSecret}" 的格式呈现,即使 tokenSecret 不存在(例如因为您正在进行身份验证流程),您也需要在那里加上 & 符号。请参见 https://developer.twitter.com/en/docs/authentication/oauth-1-0a/creating-a-signature - victorvartan

3

有一种类型叫oauth_vesrion应该是oauth_version。


0

您的签名基本参数顺序不正确。这些值按其编码名称排序,如果相等,则基于其编码值排序。因此,您的SigBaseStringParams应如下所示:

    string SigBaseStringParams = "oauth_consumer_key=" + consumerKey;
    SigBaseStringParams += "&" + "oauth_nonce=" + nonce;
    SigBaseStringParams += "&" + "oauth_signature_method=HMAC-SHA1";
    SigBaseStringParams += "&" + "oauth_timestamp=" + timeStamp;
    SigBaseStringParams += "&" + "oauth_version=1.0";

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接