2016-07-28 45 views
0

我試圖使用HTML POST表單和上載策略執行上傳到S3,我正在努力創建簽名以符合它。爲AWS請求邏輯生成簽名 - 獲取SignatureDoesNotMatch返回

當我提交上載表單時,我總是收到403和SignatureDoesNotMatch響應。

以此爲指導,http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html我已經想出了以下內容:

policy_hash = { 
    'expiration' => (Time.now.utc + 3600 * 3).iso8601 
} 

@policy = Base64.encode64(JSON.dump(policy_hash)).gsub("\n","") 

kDate = OpenSSL::HMAC.digest('sha256', "AWS4" + @secret_access_key, Time.now.strftime("%Y%m%d")) 
kRegion = OpenSSL::HMAC.digest('sha256', kDate, AWS_REGION) 
kService = OpenSSL::HMAC.digest('sha256', kRegion, "s3") 
kSigning = OpenSSL::HMAC.digest('sha256', kService, "aws4_request") 

@signature = Digest::SHA256.hexdigest(
    OpenSSL::HMAC.digest('sha256', kSigning, @policy) 
) 

而且我包括在政策和簽名。我知道AWS_REGION@secret_access_key是正確的,因爲我在別處使用它們。

任何人都可以看到上面的代碼有什麼問題嗎?或有任何其他指導?

回答

0
@signature = Digest::SHA256.hexdigest(
    OpenSSL::HMAC.digest('sha256', kSigning, @policy) 
) 

你正在做什麼應該是你的簽名,而不是十六進制編碼它,你用SHA256和十六進制編碼哈希散列它。

我不是一個紅寶石的人,但在這裏是一個瘋狂的猜測在你真正需要的:

@signature = OpenSSL::HMAC.hexdigest('sha256', kSigning, @policy) 
+0

感謝有一看,邁克爾。我決定走一條不同的路線,最終我自己不對代碼邏輯進行編碼 – user3895395

0

櫃面它的更新有助於在未來的人,我結束了使用AWS-SDK寶石爲我處理所有的簽名和表單構建。

@s3_base_path = "#{SecureRandom.uuid}/" 
creds = Aws::Credentials.new(access_key_id, secret_access_key, session_token) 
@post = Aws::S3::PresignedPost.new(creds.credentials, AWS_REGION, S3_BRANDING_FILES_BUCKET, { 
    key_starts_with: @s3_base_path, 
    acl: 'private', 
    success_action_status: '201', 
    server_side_encryption: 'AES256', 
    signature_expiration: Time.now.utc + 3600 * 3 
}) 

然後在視圖:

<!-- Direct Upload to S3 Form --> 
<form action="<%= @post.url %>" method="POST" enctype="multipart/form-data"> 
    <% @post.fields.each do |name, value| %> 
    <input type="hidden" name="<%= name %>" value="<%= value %>"/> 
    <% end %> 

    <!-- Key is the file's name on S3 and will be filled in with JS --> 
    <input type="hidden" name="key" value=""> 
    <div class="hiddenfile" style="height:0; width:0; overflow:hidden;"> 
    <input type="file" accept="image/gif, image/jpeg" name="file" id="file-input"> 
    </div> 
</form>