2014-05-04 63 views
3

我使用jquery-file-upload插件将文件直接上传到S3。我已经编写了代码来生成适当的政策文档,并根据我的知识计算了签名。以下是数据被发布到S3签名与错误不匹配 - 使用AWS签名版本4

-----------------------------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(); 

我真的很感激任何关于我在做什么的错误或我该怎么做...

回答

1

问题在于如何计算最终的signingKey

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

被散列的数据被假定为aws4_request和NOT aws4-request。在撰写本文时,AWS S3文档错误地提及[2]最终数据为aws4-request

总之,最终的签名密钥应计算如下,

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