Simon,
This came up on the CFML Slack group recently. Hmac() returns a hex string,
so you can’t use toBinary() on it. Instead you need to use
binaryDecode(string, ‘hex’). So you would have:
<cfset
string1=binaryDecode(hmac(dateformat(time,“yyyymmdd”),“AWS4#awssecret#”,“hmacsha256”),
“hex”)>
<cfset string2=binaryDecode(hmac(region,string1,“hmacsha256”), “hex”)>
<cfset string3=binaryDecode(hmac(“s3”,string2,“hmacsha256”), “hex”)>
<cfset mykey=binaryDecode(hmac(“aws4_request”,string3,“hmacsha256”),
“hex”)>
<cfset signature=lcase(hmac(mystring,mykey,“hmacsha256”))>
Note that AWS signature v4 expects a hex encoded result, so you don’t
binary decode the last line (as you have it already). Also this does mean
that the variables names ‘stringX’ will be misleading, as the signing key
for each intermediate step is in binary format.
Hope this helps,
JohnOn Wednesday, September 23, 2015 at 5:02:16 AM UTC-4, Simon Goldschmidt wrote:
I have written a simple script to upload a file to S3 using the REST API
and Signature 4… see the sample below with changed bucket, awsid and
awssecret. I was very careful with the formatting, but get a "
SignatureDoesNotMatch" response.
I noticed that sometimes the hmac() function did not return the same
result as the examples in the AWS documentation.
Am I doing something wrong here? Could it be that the hmac() function
isn’t returning what it should?
Simon
<cfif isdefined(“form.image”)>
<cfset time=dateadd(“s”,GetTimeZoneInfo().UTCTotalOffset,now())>
<cfset
myrequest=“PUT#chr(10)#http://#bucket#.#hostname#/#filename##chr(10)##chr(10)#host:#bucket#.#hostname##chr(10)#x-amz-content-sha256:#lcase(hash(payload,“sha-256”))##chr(10)#x-amz-date:#dateformat(time,“yyyymmdd”)#T#timeformat(time,“HHmmss”)#Z#chr(10)##chr(10)#host;x-amz-content-sha256;x-amz-date#chr(10)##lcase(hash(payload,“sha-256”))##chr(10)#”>
<cfset
mystring=“AWS4-HMAC-SHA256#chr(10)##dateformat(time,“yyyymmdd”)#T#timeformat(time,“HHmmss”)#Z#chr(10)##dateformat(time,“yyyymmdd”)#/#region#/s3/aws4_request#chr(10)##lcase(hash(myrequest,“sha-256”))##chr(10)#”>
<cfset
string1=tobinary(hmac(dateformat(time,“yyyymmdd”),“AWS4#awssecret#”,“hmacsha256”))>
<cfset string2=tobinary(hmac(region,string1,“hmacsha256”))>
<cfset string3=tobinary(hmac(“s3”,string2,“hmacsha256”))>
<cfset mykey=tobinary(hmac(“aws4_request”,string3,“hmacsha256”))>
<cfset signature=lcase(hmac(mystring,mykey,“hmacsha256”))>
<cfhttpparam type=“header” name=“Authorization” value=“AWS4-HMAC-SHA256
Credential=#awsid#/#dateformat(time,“yyyymmdd”)#/#region#/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=#signature#”>
<cfhttpparam type=“header” name=“x-amz-content-sha256”
value=“#lcase(hash(payload,“sha-256”))#”>
<cfhttpparam type=“header” name=“x-amz-date”
value=“#dateformat(time,“yyyymmdd”)#T#timeformat(time,“HHmmss”)#Z”>
#cfhttp.statuscode#
#cfhttp.filecontent#
> Return
Upload image: