Skip to content

Instantly share code, notes, and snippets.

@bglusman
Forked from blelump/aws_signed_request_v4.rb
Created February 26, 2016 20:50
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 bglusman/eb588154d3d8a9aeb6fe to your computer and use it in GitHub Desktop.
Save bglusman/eb588154d3d8a9aeb6fe 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}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment