2017-07-04 85 views
1

我試圖用教程http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html的HTTP post方法將圖片上傳到s3存儲桶。但我每次我們計算的請求籤名與您提供的簽名不匹配。 S3 Bucket Http Post

Error 
<Code>SignatureDoesNotMatch</Code> 
<Message> 
The request signature we calculated does not match the signature you 
provided. Check your key and signing method. 
    </Message> 

爲了讓我有以下形式的請求得到以下錯誤:

<form action="http://mynewdulibucket.s3.amazonaws.com/" method="post" enctype="multipart/form-data"> 
Key to upload: 
<input type="input" name="key" value="user/user1/${filename}" /><br /> 
<input type="hidden" name="acl" value="public-read" /> 
<input type="hidden" name="success_action_redirect" value="http://mynewdulibucket.s3.amazonaws.com/successful_upload.html" /> 
Content-Type: 
<input type="input" name="Content-Type" value="image/jpeg" /><br /> 
<input type="hidden" name="x-amz-meta-uuid" value="14365123651274" /> 
<input type="hidden" name="x-amz-server-side-encryption" value="AES256" /> 
<input type="text" name="X-Amz-Credential" value="XXXXXXXXXXXXX/20151229/us-east-1/s3/aws4_request" /> 
<input type="text" name="X-Amz-Algorithm" value="AWS4-HMAC-SHA256" /> 
<input type="text" name="X-Amz-Date" value="20151229T000000Z" /> 

Tags for File: 
<input type="input" name="x-amz-meta-tag" value="" /> <br /> 
<input type="hidden" name="Policy" value="XXXXXXXXXXXXXXX"/> 
<input type="hidden" name="X-Amz-Signature" value="XXXXXXXXXXXXX" /> 
File: 
<input type="file" name="file" /> <br /> 
<!-- The elements after this will be ignored --> 
<input type="submit" name="submit" value="Upload to Amazon S3" /> 

政策如下:

{ "expiration": "2018-12-30T12:00:00.000Z", 
"conditions": [ 
{"bucket": "mynewdulibucket"}, 
["starts-with", "$key", "user/user1/MyPhoto.jpg"], 
{"acl": "public-read"}, 
{"success_action_redirect": "http://mynewdulibucket.s3.amazonaws.com/successful_upload.html"}, 
["starts-with", "$Content-Type", "image/"], 
{"x-amz-meta-uuid": "14365123651274"}, 
{"x-amz-server-side-encryption": "AES256"}, 
["starts-with", "$x-amz-meta-tag", ""], 
{"x-amz-credential": "XXXXXXXXX/20151229/us-east-1/s3/aws4_request"}, 
{"x-amz-algorithm": "AWS4-HMAC-SHA256"}, 
{"x-amz-date": "20151229T000000Z" } 
] 
    } 

然後生成策略和簽名的代碼然後粘貼到相關的表單域中:

public class Main { 

public static void main(String[] args) throws Exception 
{ 
    String policy_document = "{\"expiration\":\"2018-12-30T12:00:00.000Z\",\"conditions\":[{\"bucket\":\"mynewdulibucket\"},[\"starts-with\",\"$key\",\"user/user1/MyPhoto.jpg\"],{\"acl\":\"public-read\"},{\"success_action_redirect\":\"http://mynewdulibucket.s3.amazonaws.com/successful_upload.html\"},[\"starts-with\",\"$Content-Type\",\"image/\"],{\"x-amz-meta-uuid\":\"14365123651274\"},{\"x-amz-server-side-encryption\":\"AES256\"},[\"starts-with\",\"$x-amz-meta-tag\",\"\"],{\"x-amz-credential\":\"AKIAJQHQNWQ7FCTGNKQQ/20151229/us-east-1/s3/aws4_request\"},{\"x-amz-algorithm\":\"AWS4-HMAC-SHA256\"},{\"x-amz-date\":\"20151229T000000Z\"}]}"; 
    String encodedPolicy = new String(Base64.getEncoder().encode(policy_document.getBytes("UTF-8"))).replaceAll("\n", "").replaceAll("\r", ""); 
    String secretKey = "XXXXXXXXXXXXXXXX"; 

    String signature = getSigning(secretKey, "20151229T000000Z", "us-east-1", "s3",encodedPolicy); 

    //the following values get pasted into the form fields Policy and X-Amz-Signature respectively (see above XXXXX) 
    System.out.println("base64 " + encodedPolicy); 

    System.out.println("signature " + signature); 

} 


static byte[] HmacSHA256(String data, byte[] key) throws Exception 
{ 
    String algorithm="HmacSHA256"; 
    Mac mac = Mac.getInstance(algorithm); 
    mac.init(new SecretKeySpec(key, algorithm)); 
    return mac.doFinal(data.getBytes("UTF8")); 
} 

static String getSigning(String key, String dateStamp, String regionName, String serviceName,String base64signature) throws Exception { 
    byte[] kSecret = ("AWS4" + key).getBytes("UTF8"); 
    byte[] kDate = HmacSHA256(dateStamp, kSecret); 
    byte[] kRegion = HmacSHA256(regionName, kDate); 
    byte[] kService = HmacSHA256(serviceName, kRegion); 
    // 
    byte[] kSigning = HmacSHA256("aws4_request", kService); 

    byte[] signature = HmacSHA256(base64signature, kSigning); 

    return new String(Base64.getEncoder().encode(signature)); 
} 
+0

只是一個供參考你的X-AMZ-日期值可能不是你想要的,因爲根據你「中午UTC之前,必須發生在2015年12月30日,上載」提供的鏈接 –

+0

是的,這就是爲什麼我」已將有效期限更改爲「過期」:「2018-12-30T12:00:00.000Z」 – george

+0

請更正指定'[「starts-with」,「$ key」,「user/user1 /」]的策略' ,再試一次,並用更正的內容更新問題。另外,不要從表格中壓制政策。它不敏感。 –

回答

0

當您未正確驗證身份時會顯示此誤導性錯誤。

驗證,要麼:

  • 你的〜/ .aws /配置是正確的。
  • 您在調用時正確提供API密鑰。
  • 您的環境變量正在正確傳遞您的憑據。
  • 您正在運行此實例的實例具有分配給其IAM角色的適當權限。
+1

我在問題中沒有看到任何證據。很明顯,〜/ .aws/config甚至可以被讀取,沒有對環境變量的引用,「API密鑰」是硬編碼的靜態字符串,並且沒有使用IAM角色。 –

+0

我唯一見過AWS在S3調用中發出簽名錯誤的時候,就會發現請求者沒有正確地進行身份驗證。我錯過了什麼嗎?如果願意,更多學習! –

+1

不匹配的密鑰和祕密,或者密碼中的錯字會導致簽名不匹配,是的。這裏的問題是您提出的具體建議與問題中提供的材料不匹配。沒有使用角色,OP直接簽署請求,不使用SDK。假設憑證中的字符串secretKey =「XXXXXXXXXXXXXXXX」;和'AKIA ...'是正確的,則問題必須出現在OP簽名算法中,或者簽名策略與策略要驗證的請求不完全匹配。 –

相關問題