Azure REST API - 服务器无法进行身份验证

时间:2015-09-03 20:27:12

标签: c# azure windows-runtime windows-phone-8.1 sha256

我正在创建能够将一些blob上传到Azure存储的Windows Phone 8.1 Store App。我不能使用WindowsAzure.Storage lib(非常奇怪),所以我试图使用REST。我无法弄清楚,有什么不对。

try
{
    string time = DateTime.Now.ToString("R", System.Globalization.CultureInfo.InvariantCulture);
    string tosign = "GET\n" +
                        "\n" +  //Content-Encoding
                        "\n" +  //Content-Language
                        "0\n" +  //Content-Length
                        "\n" +  //Content-MD5
                        "\n" +  //Content-Type
                        "\n" +  //Date
                        "\n" +  //If-modified-since
                        "\n" +  //If-match
                        "\n" +  //If-none-match
                        "\n" +  //If-unmodified-since
                        "\n" +  //Range
                        "x-ms-date:" + time + "\nx-ms-version:2015-02-21\n" +   //CanonicalizedHeaders
                        "/storage_name/\ncomp:list";    //CanonicalizedResource

    string hashKey = "DHpNuYG5MXhamfbKmFPClUlNi38QiM2uqIqz07pgvpv2gmXJRwxaMlcV05pFCYsrelGYKPed9QphyJ/YnUrh5w=="; //Primary access key

    MacAlgorithmProvider macAlgorithmProvider = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha256);
    var messageBuffer = CryptographicBuffer.ConvertStringToBinary(tosign, BinaryStringEncoding.Utf8);
    IBuffer keyBuffer = CryptographicBuffer.ConvertStringToBinary(hashKey, BinaryStringEncoding.Utf8);
    CryptographicKey hmacKey = macAlgorithmProvider.CreateKey(keyBuffer);
    IBuffer signedMessage = CryptographicEngine.Sign(hmacKey, messageBuffer);
    string hashedString = CryptographicBuffer.EncodeToBase64String(signedMessage);

    var client = new HttpClient();
    Uri uri = new Uri("https://storage_name.blob.core.windows.net/?comp=list");
    client.DefaultRequestHeaders.Add("x-ms-date", time);
    client.DefaultRequestHeaders.Add("x-ms-version", "2015-02-21");
    client.DefaultRequestHeaders.Add("Authorization", "SharedKey storage_name:" + hashedString);
    var response = await client.GetAsync(uri);
}
catch(Exception ex)
{
    Debug.WriteLine(ex.ToString());
}

错误:服务器无法验证请求。确保正确形成Authorization标头的值,包括签名。

我如何才能使它发挥作用?

2 个答案:

答案 0 :(得分:3)

您的加密代码出错了。 : - )

代码示例

以下是工作代码示例,它们在UTF-8编码的签名字符串上调用HMAC-SHA256算法,并将结果编码为Base64。"在下面的示例中, class View: UIView { func drawRooftopAtTopPointOf(point: CGPoint){ UIColor.redColor().set() let context = UIGraphicsGetCurrentContext() CGContextSetLineWidth(context, 5) CGContextMoveToPoint(context, 140, 100) CGContextAddLineToPoint(context, 140, 50) CGContextStrokePath(context) 参数是"主要访问密钥"来自Azure,hashKey参数是"签名字符串"来自docs

在Windows Phone 8.1上编码签名

在Windows Phone 8.1上,我们使用toSign命名空间,如下所示:

Windows.Security.Cryptography

在.NET中编码签名

我还创建了使用public string GetEncodedSignature(string toSign, string hashKey) { // UTF-8-encoded signature string var utf8 = BinaryStringEncoding.Utf8; var msgBuffer = CryptographicBuffer.ConvertStringToBinary(toSign, utf8); // primary access key // note the use of DecodeFromBase64String var keyBuffer = CryptographicBuffer.DecodeFromBase64String(hashKey); // make the HMAC-SHA256 algorithm var alg = MacAlgorithmNames.HmacSha256; var objMacProv = MacAlgorithmProvider.OpenAlgorithm(alg); CryptographicHash hash = objMacProv.CreateHash(keyBuffer); // call the HMAC-SHA256 algorithm hash.Append(msgBuffer); IBuffer hashMsg = hash.GetValueAndReset(); // retrieve the result! var result = CryptographicBuffer.EncodeToBase64String(hashMsg); return result; } 命名空间的an example for .NET

System.Security.Cryptography

两个代码示例在给定相同输入时产生相同的编码签名。您可以在此Fiddle that generates the HTTP Request更详细地查看其中一个。

另见

MSDN Article Authentication for the Azure Storage Services

答案 1 :(得分:1)

可能你已经解决了这个问题,但如果没有,或者对于其他任何人,我只是遇到了同样的问题,对我而言,修复它的内容是将内容长度改为" \ n& #34; (而不是" 0 \ n")。从2015-02-21及更高版本开始,您无需指定长度。

try
{
    string time = DateTime.Now.ToString("R", System.Globalization.CultureInfo.InvariantCulture);
    string tosign = "GET\n" +
                        "\n" +  //Content-Encoding
                        "\n" +  //Content-Language
                        "\n" +  //Content-Length
                        "\n" +  //Content-MD5
                        "\n" +  //Content-Type
                        "\n" +  //Date
                        "\n" +  //If-modified-since
                        "\n" +  //If-match
                        "\n" +  //If-none-match
                        "\n" +  //If-unmodified-since
                        "\n" +  //Range
                        "x-ms-date:" + time + "\nx-ms-version:2015-02-21\n" +   //CanonicalizedHeaders
                        "/storage_name/\ncomp:list";    //CanonicalizedResource

    string hashKey = "DHpNuYG5MXhamfbKmFPClUlNi38QiM2uqIqz07pgvpv2gmXJRwxaMlcV05pFCYsrelGYKPed9QphyJ/YnUrh5w=="; //Primary access key


   string hashedString = GetEncodedSignature(tosign, hashKey); //Shaun's answer method

    var client = new HttpClient();
    Uri uri = new Uri("https://storage_name.blob.core.windows.net/?comp=list");
    client.DefaultRequestHeaders.Add("x-ms-date", time);
    client.DefaultRequestHeaders.Add("x-ms-version", "2015-02-21");
    client.DefaultRequestHeaders.Add("Authorization", "SharedKey storage_name:" + hashedString);
    var response = await client.GetAsync(uri);
}
catch(Exception ex)
{
    Debug.WriteLine(ex.ToString());
}