Skip to content

Instantly share code, notes, and snippets.

@snaka
Last active April 6, 2016 06:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snaka/7f847e33109b1e25f73786a3c438782c to your computer and use it in GitHub Desktop.
Save snaka/7f847e33109b1e25f73786a3c438782c to your computer and use it in GitHub Desktop.
Upload file to S3 with signature ver. 4
#
# POST with signature v4
#
require "base64"
require "openssl"
require "digest/sha1"
require "time"
aws_access_key_id = ENV["AWS_ACCESS_KEY_ID"]
aws_secret_key = ENV["AWS_SECRET_ACCESS_KEY"]
acl = "public-read"
s3_bucket = "mybucket"
current_time = Time.now
date = current_time.strftime("%Y%m%d")
region = "ap-northeast-1"
target_file = "test.txt"
timestamp = current_time.utc.iso8601.delete("-:")
# policy document
policy_document = <<EOS
{"expiration": "#{(current_time + 60 * 60).utc.iso8601}",
"conditions": [
{"acl": "#{acl}"},
{"bucket": "#{s3_bucket}"},
["starts-with", "$key", ""],
{"x-amz-algorithm": "AWS4-HMAC-SHA256"},
{"x-amz-credential": "#{aws_access_key_id}/#{date}/#{region}/s3/aws4_request"},
{"x-amz-date": "#{timestamp}"},
{"x-amz-server-side-encryption": "AES256"}
]
}
EOS
policy = Base64.encode64(policy_document).delete("\n")
# calc signature(v4)
sha256 = OpenSSL::Digest::SHA256.new
date_key = OpenSSL::HMAC.digest(sha256, "AWS4#{aws_secret_key}", date)
date_region_key = OpenSSL::HMAC.digest(sha256, date_key, region)
date_region_service_key = OpenSSL::HMAC.digest(sha256, date_region_key, "s3")
signing_key = OpenSSL::HMAC.digest(sha256, date_region_service_key, "aws4_request")
signature = OpenSSL::HMAC.hexdigest(sha256, signing_key, policy)
# upload
cmd = <<__CURL_COMMAND__
curl -v -X POST \\
-F acl="#{acl}" \\
-F key="#{target_file}" \\
-F policy="#{policy}" \\
-F x-amz-algorithm="AWS4-HMAC-SHA256" \\
-F x-amz-credential="#{aws_access_key_id}/#{date}/#{region}/s3/aws4_request" \\
-F x-amz-date="#{timestamp}" \\
-F x-amz-signature="#{signature}" \\
-F x-amz-server-side-encryption="AES256" \\
-F "file=@#{target_file}" \\
https://#{s3_bucket}.s3.amazonaws.com/
__CURL_COMMAND__
puts cmd
puts `#{cmd}`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment