Reputation: 101
Probably simple issue but pulling hair out trying to figure it out. This code to generate a signature and make a rest post to s3 works perfectly:
<cfset cs = "PUT\n\n#arguments.contentType#\n#dateTimeString#\nx-amz-acl:#arguments.acl#\nx-amz-storage-class:#arguments.storageClass#\n/#arguments.bucketName#/#arguments.keyName#">
...
<cfhttp method="PUT" url="https://s3.amazonaws.com/#arguments.bucketName#/#arguments.keyName#" timeout="#arguments.HTTPtimeout#">
<cfhttpparam type="header" name="Authorization" value="AWS #variables.accessKeyId#:#signature#">
<cfhttpparam type="header" name="Content-Type" value="#arguments.contentType#">
<cfhttpparam type="header" name="Date" value="#dateTimeString#">
<cfhttpparam type="header" name="x-amz-acl" value="#arguments.acl#">
<cfhttpparam type="header" name="x-amz-storage-class" value="#arguments.storageClass#">
<cfhttpparam type="body" value="#binaryFileData#">
</cfhttp>
But I want to add s3 managed AES256 encryption which if I understand right should be as simple as adding the x-amz-server-side-encryption header with the value of AES256 but this does not work:
<cfset cs = "PUT\n\n#arguments.contentType#\n#dateTimeString#\nx-amz-acl:#arguments.acl#\nx-amz-storage-class:#arguments.storageClass#\nx-amz-server-side-encryption:aes256\n/#arguments.bucketName#/#arguments.keyName#">
...
<cfhttp method="PUT" url="https://s3.amazonaws.com/#arguments.bucketName#/#arguments.keyName#" timeout="#arguments.HTTPtimeout#">
<cfhttpparam type="header" name="Authorization" value="AWS #variables.accessKeyId#:#signature#">
<cfhttpparam type="header" name="Content-Type" value="#arguments.contentType#">
<cfhttpparam type="header" name="Date" value="#dateTimeString#">
<cfhttpparam type="header" name="x-amz-acl" value="#arguments.acl#">
<cfhttpparam type="header" name="x-amz-storage-class" value="#arguments.storageClass#">
<cfhttpparam type="header" name="x-amz-server-side-encryption" value="aes256">
<cfhttpparam type="body" value="#binaryFileData#">
</cfhttp>
The signature method is:
<cffunction name="createSignature" returntype="string" access="public" output="false">
<cfargument name="stringIn" type="string" required="true" />
<!--- Replace "\n" with "chr(10) to get a correct digest --->
<cfset var fixedData = replace(arguments.stringIn,"\n","#chr(10)#","all")>
<!--- Calculate the hash of the information --->
<cfset var digest = HMac(fixedData, variables.secretAccessKey, "HMACSHA1", "utf-8")>
<!--- fix the returned data to be a proper signature --->
<cfset var signature = ToBase64( binaryDecode(digest, "hex" ) )>
<cfreturn signature>
</cffunction>
When trying to use encryption I get "The request signature we calculated does not match the signature you provided. Check your key and signing method."
Its not the keys themselves since I can add/remove/list just fine. I just can't add the encryption header.
Anybody tell me what is wrong?
...And I tried both 'AES256' and 'aes256' as values.
Upvotes: 2
Views: 644
Reputation: 101
Turns out it was stupid...and it took much digging to find a single line mention it in the docs.
The Amazon headers need to be listed in alphabetical order.
Moving x-amz-server-side-encryption
above x-amz-storage-class
and using AES256 solved the problem.
Upvotes: 3