-
-
Save adrianbartyczak/1a51c9fa2aae60d860ca0d70bbc686db to your computer and use it in GitHub Desktop.
| #!/usr/bin/env bash | |
| # | |
| # File: | |
| # aws-signature-creator.sh | |
| # | |
| # Description: | |
| # A signature creator for AWS signature version 4 | |
| # | |
| # References: | |
| # https://czak.pl/2015/09/15/s3-rest-api-with-curl.html | |
| # | |
| readonly AWS_ACCESS_KEY_ID='<your_access_key_id>' | |
| readonly AWS_SECRET_ACCESS_KEY='<your_secret_access_key>' | |
| readonly AWS_SERVICE='s3' | |
| readonly AWS_REGION='us-east-1' | |
| readonly AWS_S3_BUCKET_NAME='<your_bucket_name>' | |
| readonly AWS_SERVICE_ENDPOINT_URL="\ | |
| ${AWS_S3_BUCKET_NAME}.${AWS_SERVICE}.amazonaws.com" | |
| # Create an SHA-256 hash in hexadecimal. | |
| # Usage: | |
| # hash_sha256 <string> | |
| function hash_sha256 { | |
| printf "${1}" | openssl dgst -sha256 | sed 's/^.* //' | |
| } | |
| # Create an SHA-256 hmac in hexadecimal. | |
| # Usage: | |
| # hmac_sha256 <key> <data> | |
| function hmac_sha256 { | |
| key="$1" | |
| data="$2" | |
| printf "${data}" | openssl dgst -sha256 -mac HMAC -macopt "${key}" | \ | |
| sed 's/^.* //' | |
| } | |
| readonly CURRENT_DATE_DAY="$(date -u '+%Y%m%d')" | |
| readonly CURRENT_DATE_TIME="$(date -u '+%H%M%S')" | |
| readonly CURRENT_DATE_ISO8601="${CURRENT_DATE_DAY}T${CURRENT_DATE_TIME}Z" | |
| readonly HTTP_REQUEST_METHOD='GET' | |
| readonly HTTP_REQUEST_PAYLOAD='' | |
| readonly HTTP_REQUEST_PAYLOAD_HASH="$(printf "${HTTP_REQUEST_PAYLOAD}" | \ | |
| openssl dgst -sha256 | sed 's/^.* //')" | |
| readonly HTTP_CANONICAL_REQUEST_URI='/video_clips/0940.m3u8' | |
| readonly HTTP_CANONICAL_REQUEST_QUERY_STRING='' | |
| readonly HTTP_REQUEST_CONTENT_TYPE='application/x-www-form-urlencoded' | |
| readonly HTTP_CANONICAL_REQUEST_HEADERS="\ | |
| content-type:${HTTP_REQUEST_CONTENT_TYPE} | |
| host:${AWS_SERVICE_ENDPOINT_URL} | |
| x-amz-content-sha256:${HTTP_REQUEST_PAYLOAD_HASH} | |
| x-amz-date:${CURRENT_DATE_ISO8601}" | |
| # Note: The signed headers must match the canonical request headers. | |
| readonly HTTP_REQUEST_SIGNED_HEADERS="\ | |
| content-type;host;x-amz-content-sha256;x-amz-date" | |
| readonly HTTP_CANONICAL_REQUEST="\ | |
| ${HTTP_REQUEST_METHOD} | |
| ${HTTP_CANONICAL_REQUEST_URI} | |
| ${HTTP_CANONICAL_REQUEST_QUERY_STRING} | |
| ${HTTP_CANONICAL_REQUEST_HEADERS}\n | |
| ${HTTP_REQUEST_SIGNED_HEADERS} | |
| ${HTTP_REQUEST_PAYLOAD_HASH}" | |
| # Create the signature. | |
| # Usage: | |
| # create_signature | |
| function create_signature { | |
| stringToSign="AWS4-HMAC-SHA256 | |
| ${CURRENT_DATE_ISO8601} | |
| ${CURRENT_DATE_DAY}/${AWS_REGION}/${AWS_SERVICE}/aws4_request | |
| $(hash_sha256 "${HTTP_CANONICAL_REQUEST}")" | |
| dateKey=$(hmac_sha256 key:"AWS4${AWS_SECRET_ACCESS_KEY}" \ | |
| "${CURRENT_DATE_DAY}") | |
| regionKey=$(hmac_sha256 hexkey:"${dateKey}" "${AWS_REGION}") | |
| serviceKey=$(hmac_sha256 hexkey:"${regionKey}" "${AWS_SERVICE}") | |
| signingKey=$(hmac_sha256 hexkey:"${serviceKey}" "aws4_request") | |
| printf "${stringToSign}" | openssl dgst -sha256 -mac HMAC -macopt \ | |
| hexkey:"${signingKey}" | awk '{print $2}' | |
| } | |
| readonly SIGNATURE="$(create_signature)" | |
| readonly HTTP_REQUEST_AUTHORIZATION_HEADER="\ | |
| AWS4-HMAC-SHA256 Credential=${AWS_ACCESS_KEY_ID}/${CURRENT_DATE_DAY}/\ | |
| ${AWS_REGION}/${AWS_SERVICE}/aws4_request, \ | |
| SignedHeaders=${HTTP_REQUEST_SIGNED_HEADERS};x-amz-date, Signature=${SIGNATURE}" | |
| curl -X "${HTTP_REQUEST_METHOD}" -v \ | |
| "https://${AWS_SERVICE_ENDPOINT_URL}${HTTP_CANONICAL_REQUEST_URI}" \ | |
| -H "Authorization: ${HTTP_REQUEST_AUTHORIZATION_HEADER}" \ | |
| -H "content-type: ${HTTP_REQUEST_CONTENT_TYPE}" \ | |
| -H "x-amz-content-sha256: ${HTTP_REQUEST_PAYLOAD_HASH}" \ | |
| -H "x-amz-date: ${CURRENT_DATE_ISO8601}" |
Could you please help how to upload a file to S3 bucket using similar method?
I figured out something interesting:
This script works just fine on Linux, however, if you want to run it on Mac OS X/terminal, you would need to change line 83 into
hexkey:"${signingKey}" | awk '{print $0}'
In the first 24 hours of creating a bucket, this script is likely to fail unless you change line 19 to:
${AWS_S3_BUCKET_NAME}.${AWS_SERVICE}-${AWS_REGION}.amazonaws.com"
Refer this issue: https://aws.amazon.com/premiumsupport/knowledge-center/s3-http-307-response/
@ManfredServoy, even more interesting is that it works as is on some Macs with Catalina and not with others... setting it to $0 as you have done seems to make it work on all Macs. Really curious what makes some Macs susceptible.
Could you please help how to upload a file to S3 bucket using similar method?
Could you please help how to upload a file to S3 bucket using similar method?
https://gist.github.com/ambanmba/6ec9f2ba1afdc07711b2cc4aa63eabcf
That's the one I use to push stuff to S3. Just keep in mind that the credentials in IAM need to allow WRITE.
Thanks. It is great.
Somehow, create_signature returns an empty string for me