使用するには
- 環境変数 AWS_SECRET_ACCESS_KEY にシークレットアクセスキー
- 環境変数 AWS_ACCESS_KEY_ID にアクセスキーID
- s3_bucket に対象のバケット名
- region にバケットのリージョン
- target_file にアップロード対象のファイル名
をそれぞれ設定する必要あり
実行方法は ruby s3upload_signature_v4.rb
のように実行。
コード
s3upload_signature_v4.rb
#
# 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 = "private"
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}`
補足
s3 へPOSTでファイルをアップロードする(署名バージョン2) の補足も参考に