Skip to content

Instantly share code, notes, and snippets.

@Sparticuz
Created January 18, 2017 19:47
Show Gist options
  • Save Sparticuz/e5dcfb3bc3b21a6dc850f64e8fb27fac to your computer and use it in GitHub Desktop.
Save Sparticuz/e5dcfb3bc3b21a6dc850f64e8fb27fac to your computer and use it in GitHub Desktop.
FUNCTION lf AS C (count AS N = 1)
dim return as c = ""
while count
*concat(return,chr(10))
count = count - 1
end while
lf = return
END FUNCTION
function hmacsha256 as b (message as c, key as b)
dim Encoding as p = new ::System::Text::Encoding::UTF8
dim kha as ::System::Security::Cryptography::KeyedHashAlgorithm = new ::System::Security::Cryptography::KeyedHashAlgorithm::Create("HMACSHA256")
'Set the key
kha.Key = key
hmacsha256 = kha.ComputeHash(Encoding.GetBytes(message))
end function
function getSignatureKey as b (key as c, dateStamp as c, regionName as c, serviceName as c)
dim test as l = .f.
if test then
key = "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY"
dateStamp = "20120215"
regionName = "us-east-1"
serviceName= "iam"
'*to_hex()
'kSecret = '41575334774a616c725855746e46454d492f4b374d44454e472b62507852666943594558414d504c454b4559'
'kDate = '969fbb94feb542b71ede6f87fe4d5fa29c789342b0f407474670f0c2489e0a0d'
'kRegion = '69daa0209cd9c5ff5c8ced464a696fd4252e981430b10e3d3fd8e2f197d7a70c'
'kService = 'f72cfd46f26bc4643f06a11eabb6c0ba18780c19a8da0c31ace671265e3c87fa'
'kSigning = 'f4780e2d9f65fa895f9c67b32ce1baf0b0d8a43505a000a1a9e090d414db404d'
end if
dim Encoding as p = new ::System::Text::Encoding::UTF8
dim kSecret as b = Encoding.GetBytes("AWS4"+key)
dim kDate as b = hmacsha256(dateStamp,kSecret)
dim kRegion as b = hmacsha256(regionName,kDate)
dim kService as b = hmacsha256(serviceName,kRegion)
dim kSigning as b = hmacsha256("aws4_request",kService)
getSignatureKey = kSigning
end function
function sha256 as c (string as c)
dim Encoding as p = new ::System::Text::Encoding::UTF8
dim sham as ::System::Security::Cryptography::SHA256Managed = new ::System::Security::Cryptography::SHA256Managed()
sha256 = *to_hex(sham.ComputeHash(Encoding.GetBytes(string)))
end function
function getAccessKey as c ()
getAccessKey = ""
end function
function getSecretKey as c ()
getSecretKey = ""
end function
function getSignature as c (verb as c, method as c, query as p, payload as c = "", serviceName as c = "ses", regionName as c = "us-east-1")
'# ************* TASK 1: CREATE A CANONICAL REQUEST *************
'http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
dim datetime as t = now(.t.)
dim amzdate as c = time("yyyyMMddT0h0m0sZ",datetime)
dim datestamp as c = time("yyyyMMdd",datetime)
dim access_key as c = getAccessKey()
dim secret_key as c = getSecretKey()
dim host as c = "email."+regionName+".amazonaws.com"
dim test as l = .f.
if test then
amzdate = "20150830T123600Z"
datestamp = "20150830"
access_key = "AKIDEXAMPLE"
secret_key = "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY"
host = "example.amazonaws.com"
serviceName = "service"
regionName = "us-east-1"
delete query
dim query as p
query.Param1 = "value1"
query.Param2 = "value2"
debug(1)
end if
'Step 1 is to define the verb (GET, POST, etc.)--already done by passing verb.
'Step 2: Create canonical URI--the part of the URI from domain to query
' string (use '/' if no path)
dim uri as c = method
'Step 3: Create the canonical query string. In this example (a GET request),
' request parameters are in the query string. Query string values must
' be URL-encoded (space=%20). The parameters must be sorted by name.
' For this example, the query string is pre-formatted in the request_parameters variable.
dim queryString as c = property_to_url(query,"S")
'Step 4: Create the canonical headers and signed headers. Header names
' and value must be trimmed and lowercase, and sorted in ASCII order.
' Note that there is a trailing \n.
dim headers as c = "host:"+host+lf()+"x-amz-date:"+amzdate+lf()
'Step 5: Create the list of signed headers. This lists the headers
' in the canonical_headers list, delimited with ";" and in alpha order.
' Note: The request can include any headers; canonical_headers and
' signed_headers lists those that you want to be included in the
' hash of the request. "Host" and "x-amz-date" are always required.
dim signedHeaders as c = "host;x-amz-date"
'Step 6: Create payload hash (hash of the request body content). For GET
' requests, the payload is an empty string ("").
if verb == "GET" then
dim payloadHash as c = sha256("")
else
dim payloadHash as c = sha256(payload)
end if
' Step 7: Combine elements to create create canonical request
dim canonical_request as c = alltrim(verb) + lf() + alltrim(uri) + lf()
if queryString <> "" then
*concat(canonical_request,alltrim(queryString) + lf())
end if
*concat(canonical_request,alltrim(headers) + lf(2) + alltrim(signedHeaders) + lf() + alltrim(payloadHash))
'# ************* TASK 2: CREATE THE STRING TO SIGN*************
'Match the algorithm to the hashing algorithm you use, either SHA-1 or
' SHA-256 (recommended)
dim algorithm as c = "AWS4-HMAC-SHA256"
dim credentialScope as c = datestamp + "/" + regionName + "/" + serviceName + "/aws4_request"
dim canonicalHash as c = sha256(canonical_request)
dim stringToSign as c = algorithm + lf() + amzdate + lf() + credentialScope + lf() + canonicalHash
'# ************* TASK 3: CALCULATE THE SIGNATURE *************
' Create the signing key using the function defined above.
dim signingKey as b = getSignatureKey(secret_key, datestamp, regionName, serviceName)
' Sign the string_to_sign using the signing_key
dim signature as c = *to_hex(hmacsha256(stringToSign,signingKey))
'# ************* TASK 4: ADD SIGNING INFORMATION TO THE REQUEST *************
'# The signing information can be either in a query string value or in
'# a header named Authorization. This code shows how to use a header.
'# Create authorization header and add to request headers
dim authorization_header as c = algorithm + " " + "Credential=" + access_key + "/" + credentialScope + ", SignedHeaders=" + signedHeaders + ", Signature=" + signature
'# The request can include any headers, but MUST include "host", "x-amz-date",
'# and (for this scenario) "Authorization". "host" and "x-amz-date" must
'# be included in the canonical_headers and signed_headers, as noted
'# earlier. Order here is not significant.
'# Python note: The 'host' header is added automatically by the Python 'requests' library.
'headers = {'x-amz-date':amzdate, 'Authorization':authorization_header}
getSignature = "{'x-amz-date':'"+amzdate+"','Authorization':'"+authorization_header+"','Host':'"+host+"'}"
end function
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment