Created
February 5, 2013 18:02
-
-
Save cflove/4716338 to your computer and use it in GitHub Desktop.
Amazon AWS API URL Signature creation with ColdFusion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cffunction name="awsurl" returntype="string" access="public" output="No"> | |
<cfargument name="Query" type="string" required="true" /> | |
<cfargument name="AWSAccessKeyId" type="string" required="true" /> | |
<cfargument name="SecretKey" type="string" required="true" /> | |
<cfargument name="Host" type="string" default="ec2.amazonaws.com" /> | |
<cfargument name="Methord" type="string" default="GET" /> | |
<cfargument name="URI" type="string" default="/" /> | |
<cfargument name="SignatureVersion" type="string" default="2" /> | |
<cfargument name="Version" type="date" default="2012-04-01" /> | |
<cfargument name="http" type="string" default="https" hint="https|http" /> | |
<!--- add common values ---> | |
<cfset local.Time = dateConvert("local2Utc",now())> | |
<cfset local.Time = "#DateFormat(local.Time,'yyyy-mm-dd')#T#TimeFormat(local.Time,'HH:mm:ss')#"> | |
<cfset arguments.Query = "#arguments.Query#&Timestamp=#local.Time#&SignatureVersion=#arguments.SignatureVersion#&Version=#arguments.Version#&SignatureMethod=HmacSHA256"> | |
<!--- sort QueryString ---> | |
<cfset arguments.Query = ListToArray(arguments.Query,'&')> | |
<cfset ArraySort(arguments.Query,'text')> | |
<!--- prepend AccessKeyID ---> | |
<cfset ArrayPrepend(arguments.Query, "AWSAccessKeyId=#arguments.AWSAccessKeyId#")> | |
<!--- url encode each values ---> | |
<cfset local.SortedString = ArrayNew(1)> | |
<cfloop from="1" to="#ArrayLen(arguments.Query)#" index="local.i"> | |
<cfset local.value = arguments.Query[local.i]> | |
<cfif listlen(local.value,'=') gt 1> | |
<cfset ArrayAppend(local.SortedString,"#listfirst(local.value,'=')#=#reservedEncod(listlast(local.value,'='))#")> | |
<cfelse> | |
<cfset ArrayAppend(local.SortedString,"#local.value#")> | |
</cfif> | |
</cfloop> | |
<!--- create signature string ---> | |
<cfset local.toEncode = "#arguments.Methord##chr(10)##arguments.Host##chr(10)##arguments.URI##chr(10)##ArrayToList(local.SortedString,'&')#"> | |
<cfoutput><pre>#local.toEncode#</pre></cfoutput> | |
<!--- encode Signature String ---> | |
<cfset local.Signature = URLEncodedFormat(ToBase64(HMAC_SHA256(local.toEncode,arguments.SecretKey)))> | |
<cfset arguments.Query = ArrayToList(arguments.Query,'&')> | |
<cfset arguments.Query = "#arguments.http#://#arguments.Host##arguments.URI#?#arguments.Query#&Signature=#local.Signature#"> | |
<cfreturn arguments.Query> | |
</cffunction> | |
<cffunction name="reservedEncod" returntype="string" access="public" output="no"> | |
<cfargument name="string" type="string" required="true" /> | |
<cfset local.reserved = "!|##|$|&|'|(|)|*|+|,|/|:|;|=|?|@|[|]| "> | |
<cfloop list="#local.reserved#" index="local.i" delimiters="|"> | |
<cfif find(local.i,arguments.string)> | |
<cfset arguments.string = replace(arguments.string,local.i, "%#ucase(FormatBaseN(Asc(local.i),'16'))#", 'all')> | |
</cfif> | |
</cfloop> | |
<cfreturn arguments.string> | |
</cffunction> | |
<cffunction name="HMAC_SHA256" returntype="binary" access="public" output="no"> | |
<cfargument name="signMessage" type="string" required="true" /> | |
<cfargument name="signKey" type="string" required="true" /> | |
<cfset local.jMsg = JavaCast("string",arguments.signMessage).getBytes("iso-8859-1") /> | |
<cfset local.jKey = JavaCast("string",arguments.signKey).getBytes("iso-8859-1") /> | |
<cfset local.key = createObject("java","javax.crypto.spec.SecretKeySpec") /> | |
<cfset local.mac = createObject("java","javax.crypto.Mac") /> | |
<cfset local.key = local.key.init(local.jKey,"HmacSHA256") /> | |
<cfset local.mac = local.mac.getInstance(local.key.getAlgorithm()) /> | |
<cfset local.mac.init(local.key) /> | |
<cfset local.mac.update(local.jMsg) /> | |
<cfreturn local.mac.doFinal() /> | |
</cffunction> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I cant seem to get HMAC_SHA256 function to generate the proper signature according to the response from amazon. Do you have an updated solution?