2016-07-28 117 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>