c# - 签名不匹配错误 - 使用 AWS 签名版本 4

标签 c# amazon-web-services amazon-s3 jquery-file-upload

我使用 jquery-file-upload 插件直接将文件上传到 S3。我已经编写了代码来生成适当的策略文档,并尽我所知计算了签名。以下是发布到S3的数据

-----------------------------233832764916806 Content-Disposition: form-data; name="key" 50121d1ccb3f3f04400203ab/5365aa6fe104842054008a71.log 
-----------------------------233832764916806 Content-Disposition: form-data; name="acl" private 
-----------------------------233832764916806 Content-Disposition: form-data; name="Policy" eyAiZXhwaXJhdGlvbiIgOiAiMjAxNC0wNS0wNFQwMzo0ODoxNS4wMDBaIiwgImNvbmRpdGlvbnMiIDogW1siZXEiLCAiJGFjbCIsICJwcml2YXRlIl0sIFsiZXEiLCAiJGJ1Y2tldCIsICJmaXJtemVuLWRvY3VtZW50LXVwbG9hZHMiXSwgWyJzdGFydHMtd2l0aCIsICIka2V5IiwgIjUwMTIxZDFjY2IzZjNmMDQ0MDAyMDNhYi8iXSwgWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsIDAsIE51bWJlckxvbmWFtei1kYXRlIiwgIjIwMTcoNTI0Mjg4MCldLCBbImVxIiwgIiR4LQwNTA0VDAwMDAwMFoiXSwgWyJlcSIsICIkeC1hbXotYWxnb3JpdGhtIiwgIkFXUzQtSE1BQy1TSEEyNTYiXSwgWyJlcSIsICIkeC1hbXotY3JlZGVudGlhbCIsICJBS0lBSUczSFZEUzZCRllaNE1NUS8yMDE0MDUwNC9hcC1zb3V0aGVhc3QtMS9zMy9hd3M0X3JlcXVlc3QiXV0gfQ== 
-----------------------------233832764916806 Content-Disposition: form-data; name="X-Amz-Algorithm" AWS4-HMAC-SHA256 
-----------------------------233832764916806 Content-Disposition: form-data; name="X-Amz-Credential" AKIHVDSAIG36BFYZ4MMQ/20140504/ap-southeast-1/s3/aws4_request 
-----------------------------233832764916806 Content-Disposition: form-data; name="X-Amz-Date" 20140504T000000Z 
-----------------------------233832764916806 Content-Disposition: form-data; name="X-Amz-Signature" 6d675b1a24ccd5e4299faaac4218fe27949fb3ac38bd7ccfb7b213195a014682 
-----------------------------233832764916806 Content-Disposition: form-data; name="file"; filename="test.log" Content-Type: application/octet-stream

收到的错误响应是

<error>
    <code>SignatureDoesNotMatch</code>
    <message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</message>
    <stringtosignbytes>hex string</stringtosignbytes>
    <requestid>C2CAD41FF4687E39</requestid>
    <hostid>52UqNeMK28UEydmQx/I/jy/3fsMdKo0UtRAbZnXkfB2aEk35A2bjkciJvNzRktdt</hostid>
    <signatureprovided>6d675b1a24ccd5e4299faaac4218fe27949fb3ac38bd7ccfb7b213195a014682</signatureprovided>
    <stringtosign>eyAiZXhwaXJhdGlvbiIgOiAiMjAxNC0wNS0wNFQwMzo0ODoxNS4wMDBaIiwgImNvbmRpdGlvbnMiIDogW1siZXEiLCAiJGFjbCIsICJwcml2YXRlIl0sIFsiZXEiLCAiJGJ1Y2tldCIsICJmaXJtemVuLWRvY3VtZW50LXVwbG9hZHMiXSwgWyJzdGFydHMtd2l0aCIsICIka2V5IiwgIjUwMTIxZDFjY2IzZjNmMDQ0MDAyMDNhYi8iXSwgWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsIDAsIE51bWJlckxvbmWFtei1kYXRlIiwgIjIwMTcoNTI0Mjg4MCldLCBbImVxIiwgIiR4LQwNTA0VDAwMDAwMFoiXSwgWyJlcSIsICIkeC1hbXotYWxnb3JpdGhtIiwgIkFXUzQtSE1BQy1TSEEyNTYiXSwgWyJlcSIsICIkeC1hbXotY3JlZGVudGlhbCIsICJBS0lBSUczSFZEUzZCRllaNE1NUS8yMDE0MDUwNC9hcC1zb3V0aGVhc3QtMS9zMy9hd3M0X3JlcXVlc3QiXV0gfQ==</stringtosign>
    <awsaccesskeyid>AKIHVDSAIG36BFYZ4MMQ</awsaccesskeyid>
</error>

我正在使用以下 C# 代码生成策略并对其进行签名

var extension = Path.GetExtension(fileName);
var fileId = ObjectId.GenerateNewId();
var key = string.Format("{0}/{1}{2}", _firm.Id, fileId, extension);
var keyMatchCondition = string.Format("{0}/", _firm.Id);
var utcNow = DateTime.UtcNow;
var dateString = utcNow.Date.ToString("yyyyMMdd"); // 20140504
var amzCredentialString = string.Format("{0}/{1}/{2}/s3/aws4_request",
                                        <AWSAccessKey>,
                                        dateString,
                                        "ap-southeast-1");
const string awsAlgorithm = "AWS4-HMAC-SHA256";
var conditions = 
    new List<dynamic[]>
    {
        new dynamic[] {"eq", "$acl", "private"},
        new dynamic[] {"eq", "$bucket", _commonConfig.S3Config.DocumentsBucket},
        new dynamic[] {"starts-with", "$key", keyMatchCondition},
        new dynamic[] {"content-length-range", 0, 1 * 1024 * 1024},
        // utcNow.Date.ToAwsIS08601String() == 20140504T000000Z
        new dynamic[] {"eq", "$x-amz-date", utcNow.Date.ToAwsIS08601String()}, 
        new dynamic[] {"eq", "$x-amz-algorithm", awsAlgorithm},
        new dynamic[] {"eq", "$x-amz-credential", amzCredentialString},
    };
var expiration = utcNow.AddHours(1).ToString("yyyy-MM-ddTHH:mm:ss.000Z", CultureInfo.InvariantCulture);
var policyJson = new {expiration = expiration, conditions = conditions}.ToJson();
var policyBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(policyJson));

var dateKey = new HMACSHA256(Encoding.UTF8.GetBytes("AWS4" + "<secret-key>"))
    .ComputeHash(Encoding.UTF8.GetBytes(dateString));
var dateRegionKey = new HMACSHA256(dateKey)
    .ComputeHash(Encoding.UTF8.GetBytes("ap-southeast-1"));
var dateRegionServiceKey = new HMACSHA256(dateRegionKey)
    .ComputeHash(Encoding.UTF8.GetBytes("s3"));
var signingKey = new HMACSHA256(dateRegionServiceKey)
    .ComputeHash(Encoding.UTF8.GetBytes("aws4-request"));
var signedPolicyBytes = new HMACSHA256(signingKey)
    .ComputeHash(Encoding.UTF8.GetBytes(policyBase64));
var signature = BitConverter.ToString(signedPolicyBytes).Replace("-", string.Empty).ToLowerInvariant();

我非常感谢任何关于我做错了什么或我应该如何做的指示......

最佳答案

问题在于最终的 signingKey 是如何产生的被计算。

var signingKey = new HMACSHA256(dateRegionServiceKey)
    .ComputeHash(Encoding.UTF8.GetBytes("aws4-request"));

要散列的数据应该是aws4_request而不是 aws4-request .在撰写本文时,AWS S3 文档错误地 [ 1 ]提到[2 ] 最终数据为aws4-request .

总而言之,最终的签名 key 应按如下方式计算,

var signingKey = new HMACSHA256(dateRegionServiceKey)
    .ComputeHash(Encoding.UTF8.GetBytes("aws4_request"));

关于c# - 签名不匹配错误 - 使用 AWS 签名版本 4,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23451857/

相关文章:

c# - 如何通过友好名称打开串口?

c# - 显示时间填充 Stackoverflow 和 Facebook 是如何做的 - C#

python - Amazon SageMaker 中的 Tensorflow 服务

amazon-web-services - Elastic Beanstalk : ERROR: The EB CLI cannot find a platform for key "docker 17.03.1-ce"

java - "recursively"抓取S3子文件夹中的所有文件

amazon-s3 - CloudFront - 来自自定义来源的私有(private)内容?

javascript - 将 JSON 文件从 S3 存储桶加载到 React 组件

c# - 我在这个 LINQ 语句中做错了什么?

c# - 如何获得总 CPU 使用率(所有进程)? (C#)

amazon-web-services - 在 AWS Cloudformation 中创建跨账户 IAM 角色时,如何在策略的 Condition 元素中使用 !if