Skip to content

Instantly share code, notes, and snippets.

@blelump
Last active December 8, 2022 15:51
Show Gist options
  • Star 26 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save blelump/9e6880a87fefa6397032 to your computer and use it in GitHub Desktop.
Save blelump/9e6880a87fefa6397032 to your computer and use it in GitHub Desktop.
Sample Ruby code to create AWS signed request version 4 (with request headers)
#Signing AWS Requests By Using Signature Version 4
#http://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html
require 'uri'
require 'openssl'
require 'net/http'
require 'cgi'
method = 'GET'
service = 'iam'
host = 'iam.amazonaws.com'
region = 'eu-west-1'
endpoint = 'https://iam.amazonaws.com'
request_parameters = {
"Action" => "CreateUser",
"UserName" => "NewUser"
}.collect do |k,v|
out = ""
if v.kind_of?(Hash)
v.each do |kk,vv|
out += "#{k}.#{kk}=#{vv}"
end
else
out += "#{k}=#{v}"
end
out
end.join("&")
t = Time.now.utc
amzdate = t.strftime('%Y%m%dT%H%M%SZ')
datestamp = t.strftime('%Y%m%d')
def getSignatureKey(key, dateStamp, regionName, serviceName)
kDate = OpenSSL::HMAC.digest('sha256', "AWS4" + key, dateStamp)
kRegion = OpenSSL::HMAC.digest('sha256', kDate, regionName)
kService = OpenSSL::HMAC.digest('sha256', kRegion, serviceName)
kSigning = OpenSSL::HMAC.digest('sha256', kService, "aws4_request")
kSigning
end
access_key = "ACCESS_KEY"
secret_key = "SECRET_KEY"
# Task 1: Create a Canonical Request For Signature Version 4
# http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
canonical_uri = '/'
signed_headers = 'content-type;host;x-amz-content-sha256;x-amz-date'
payload_hash = OpenSSL::Digest::Digest.new("sha256").hexdigest("")
canonical_headers = ['content-type:application/x-www-form-urlencoded; charset=utf-8',
'host:' + host, "x-amz-content-sha256:#{payload_hash}",
'x-amz-date:' + amzdate].join("\n") + "\n"
canonical_request = [method, canonical_uri, request_parameters, canonical_headers,
signed_headers, payload_hash].join("\n")
# Task 2: Create a String to Sign for Signature Version 4
# http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html
algorithm = 'AWS4-HMAC-SHA256'
credential_scope = [datestamp, region, service, 'aws4_request'].join("/")
string_to_sign = [
algorithm, amzdate, credential_scope,
OpenSSL::Digest::Digest.new("sha256").hexdigest(canonical_request)
].join("\n")
# Task 3: Calculate the AWS Signature Version 4
# http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
signing_key = getSignatureKey(secret_key, datestamp, region, service)
# Task 4: Add the Signing Information to the Request
# http://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html
signature = OpenSSL::HMAC.hexdigest('sha256', signing_key, string_to_sign)
uri = URI.parse(endpoint)
https = Net::HTTP.new(uri.host,uri.port)
https.use_ssl = true
request = Net::HTTP::Get.new("#{canonical_uri}#{'?' + request_parameters}")
auth = "#{algorithm} Credential=#{access_key + '/' + credential_scope}, SignedHeaders=#{signed_headers}, Signature=#{signature}"
request.add_field 'Content-Type', "application/x-www-form-urlencoded; charset=utf-8"
request.add_field 'X-Amz-Date', amzdate
request.add_field 'X-Amz-Content-Sha256', payload_hash
request.add_field 'Authorization', auth
res = https.request(request)
puts "#{res.code} #{res.message}"
@liquean
Copy link

liquean commented Aug 15, 2017

Thanks for it!!

Do you know what changes have to be made to do a POST request with a body in JSON with AWS Signature v4?

@itrustgod
Copy link

hey ive been trying to get this to work implament it to my script but sense i know nothing about code im looking to pay someone to have this added to my script please contact me ontime24seven@gmail.com

@alexlopes
Copy link

Thanks!! 🍻

@mayurpathak
Copy link

Hello @blelump

I got an error in this script file can you please help pe

"message": "{\n \"errors\": [\n {\n \"message\": \"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.\n\nThe Canonical String for this request should have been\n'GET\n/catalog/2022-04-01/items/B081MRQH8K\nincludedData=attributes%2Cdimensions%2Cidentifiers%2Cimages%2CproductTypes%2CsalesRanks%2Csummaries%2Crelationships&locale=ja_JP&marketplaceIds=A1VC38T7YXB528\naccept:application/json\nhost:sellingpartnerapi-fe.amazon.com\nx-amz-access-token:Atza|IwEBICNvZQeAkFCU4POCCPZgZjJOzYTkIixs9k8lLMx4EdAngBCaQiDCzqmtcK9ZT4fkD4cLpqX1viA_5hABL62ztWiw0-qpTLrxp1wS4pJ5Z35b7biv5WkxpO5EB1HAkbN3xU-LEPKlqqw6986Fx-QTQbxd2gs5s0JT9KciioZN1H-CQ0F2dDNcVNZF2nmlYnq_OjSc5u-UEmpYFhXzZD5dDPlvpkbQlExRzS9dkrm68WAzvWHKxny6O96bLRBimQfK8574Gd7yvxxWOQGe9suTvTW5i-LTk8zDA07xL_HZmbnZRr4mDw61Ua4gsxbuSNBamYnWlgFXDaU0lbTO_BTMOheP\nx-amz-date:20220616T075449Z\n\naccept;host;x-amz-access-token;x-amz-date\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'\n\nThe String-to-Sign should have been\n'AWS4-HMAC-SHA256\n20220616T075449Z\n20220616/us-west-2/execute-api/aws4_request\n9fff58a4e7b712c382d680777a375543913f63740ab110611c04d1ead9871dcf'\n\",\n \"code\": \"InvalidSignature\"\n }\n ]\n}"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment