Skip to content

Instantly share code, notes, and snippets.

@voodoodror
Last active September 19, 2023 07:52
Show Gist options
  • Save voodoodror/79917399513f9bd5652d153e5718922a to your computer and use it in GitHub Desktop.
Save voodoodror/79917399513f9bd5652d153e5718922a to your computer and use it in GitHub Desktop.
AWS Signature 4 Bash
# Currently supports GET method but few modifications should make it universal.
# script.sh <METHOD> <URL>
# Note that this script isn't S3 upload compatible!
ACCESS_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
SECRET_KEY="YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
DATE=$(date -u +"%Y%m%dT%H%M%SZ")
DATE_ONLY=$(date -u +"%Y%m%d")
REGION="us-east-1"
SERVICE="execute-api"
ALGORITHM="AWS4-HMAC-SHA256"
SIGNED_HEADERS="host;x-amz-date"
# Taken from http://danosipov.com/?p=496
function sign {
kSecret=$(printf "AWS4$1" | xxd -p -c 256)
kDate=$(printf "$2" | openssl dgst -binary -sha256 -mac HMAC -macopt hexkey:$kSecret | xxd -p -c 256)
kRegion=$(printf "$3" | openssl dgst -binary -sha256 -mac HMAC -macopt hexkey:$kDate | xxd -p -c 256)
kService=$(printf "$4" | openssl dgst -binary -sha256 -mac HMAC -macopt hexkey:$kRegion | xxd -p -c 256)
kSigning=$(printf "aws4_request" | openssl dgst -binary -sha256 -mac HMAC -macopt hexkey:$kService | xxd -p -c 256)
printf $kSigning
}
# URI Parser taken from https://gist.github.com/leesei/6668590
function uri_parser() {
# uri capture
uri="$@"
# safe escaping
uri="${uri//\`/%60}"
uri="${uri//\"/%22}"
# top level parsing
pattern='^(([a-z]{3,5})://)?((([^:\/]+)(:([^@\/]*))?@)?([^:\/?]+)(:([0-9]+))?)(\/[^?]*)?(\?[^#]*)?(#.*)?$'
[[ "$uri" =~ $pattern ]] || return 1;
# component extraction
uri=${BASH_REMATCH[0]}
uri_schema=${BASH_REMATCH[2]}
uri_address=${BASH_REMATCH[3]}
uri_user=${BASH_REMATCH[5]}
uri_password=${BASH_REMATCH[7]}
uri_host=${BASH_REMATCH[8]}
uri_port=${BASH_REMATCH[10]}
uri_path=${BASH_REMATCH[11]}
uri_query=${BASH_REMATCH[12]}
uri_fragment=${BASH_REMATCH[13]}
# path parsing
count=0
path="$uri_path"
pattern='^/+([^/]+)'
while [[ $path =~ $pattern ]]; do
eval "uri_parts[$count]=\"${BASH_REMATCH[1]}\""
path="${path:${#BASH_REMATCH[0]}}"
let count++
done
# query parsing
count=0
query="$uri_query"
pattern='^[?&]+([^= ]+)(=([^&]*))?'
while [[ $query =~ $pattern ]]; do
eval "uri_args[$count]=\"${BASH_REMATCH[1]}\""
eval "uri_arg_${BASH_REMATCH[1]}=\"${BASH_REMATCH[3]}\""
query="${query:${#BASH_REMATCH[0]}}"
let count++
done
# return success
return 0
}
uri_parser $2
PAYLOAD=$(printf "" | openssl dgst -binary -sha256 | od -An -vtx1 | sed 's/[ \n]//g' | sed 'N;s/\n//')
CANONICAL_REQUEST="$1\n$uri_path\n\nhost:$uri_address\nx-amz-date:$DATE\n\nhost;x-amz-date\n$PAYLOAD"
CREDENTIAL_SCOPE="$DATE_ONLY/$REGION/$SERVICE/aws4_request"
STRING_TO_SIGN="$ALGORITHM\n$DATE\n$CREDENTIAL_SCOPE\n$(printf $CANONICAL_REQUEST | openssl dgst -binary -sha256 | od -An -vtx1 | sed 's/[ \n]//g' | sed 'N;s/\n//')"
SIGNING_KEY=$(sign $SECRET_KEY $DATE_ONLY $REGION $SERVICE)
SIGNATURE=$(printf "$STRING_TO_SIGN" | openssl dgst -binary -sha256 -mac HMAC -macopt hexkey:$SIGNING_KEY | xxd -p -c 256)
AUTHORIZATION_HEADER="$ALGORITHM Credential=$ACCESS_KEY/$CREDENTIAL_SCOPE, SignedHeaders=$SIGNED_HEADERS, Signature=$SIGNATURE"
curl --request $1 --url "$2" -H "authorization: $AUTHORIZATION_HEADER" -H "cache-control: no-cache" -H "content-type: application/json" -H "host: $uri_address" -H "x-amz-date: $DATE" -H "x-amz-content-sha256: $PAYLOAD"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment