AWS create signature for for S3 using JAVA or ColdFusion (S3)


There are following steps to create a signed request but you can also use SDK's that are available almost all programing languages 


Step 1: Create a canonical request

Create a canonical request by concatenating the following strings, separated by newline characters.

HTTPMethod
CanonicalUri
CanonicalQueryString
CanonicalHeaders
SignedHeaders
HashedPayload

 

Here is the code example of create S3 put object canonical string in COLDFUSION  


PUT\n\nimage/png\n20221227123987\nx-amz-acl:publicread\nx-amz-storage-class:standard\ntest-bucket/other.png

 

 

Step 2: Create a hash of the canonical request 
 

NSA SHA-1 Algorithm (Convert string to SHA1)

<cffunction name="HMAC_SHA1" returntype="binary" access="public" output="false">
	<cfargument name="signKey" type="string" required="true" />
	<cfargument name="signMessage" type="string" required="true" />
	<cfset var jMsg = JavaCast("string",arguments.signMessage).getBytes("iso-8859-1") />
	<cfset var jKey = JavaCast("string",arguments.signKey).getBytes("iso-8859-1") />
	<cfset var key = createObject("java","javax.crypto.spec.SecretKeySpec") />
	<cfset var mac = createObject("java","javax.crypto.Mac") />
	<cfset key = key.init(jKey,"HmacSHA1") />
	<cfset mac = mac.getInstance(key.getAlgorithm()) />
	<cfset mac.init(key) />
	<cfset mac.update(jMsg) />
	<cfreturn mac.doFinal() />
</cffunction>

 

Step 3: Create a string to sign

AWS create signature for S3 using JAVA or ColdFusion
 

<cffunction name="createSignature" returntype="string" access="public" output="false">
	<cfargument name="conicalString" type="string" required="true" />
		
	<!--- Replace "\n" with "chr(10) to get a correct digest --->
	<cfset var fixedData = replace(arguments.conicalString,"\n","#chr(10)#","all")>
		
	<!--- Calculate the hash of the information --->
	<cfset var digest = HMAC_SHA1(aws-secret-key,fixedData)>

	<!--- fix the returned data to be a proper signature --->
	<cfset var signature = ToBase64("#digest#")>
	<cfreturn signature>
</cffunction>

LAST STEP

How to send request to put object in s3
 

<cfset contentType = 'image/png'>
 <cfset dateTimeString = GetHTTPTimeString(Now())>
 <cfset filekey = 'somefolder/someImage.png'>
 <cfset acl = 'public-read'/>
 <cfset storageClass = "STANDARD"/>
 <cfset bucketName = "tes-bucket"/>
 <cfset HTTPtimeout = 300/>
 <cfset fileToUpload = 'tmp/someImage.png'/>
 
 
 <!--- Create a canonical string to send --->
 <cfset cs = "PUT\n\n#contentType#\n#dateTimeString#\nx-amz-acl:#acl#\nx-amz-storage-class:#storageClass#\n/#bucketName#/#filekey#">
 
 <!--- Create a proper signature --->
 <cfset signature = createSignature(cs)>
 
 <!--- Read the image data into a variable --->
 <cffile action="readBinary" file="#fileToUpload#" variable="binaryFileData">
 
 <!--- Send the file to amazon. The "X-amz-acl" controls the access properties of the file --->
 <cfhttp method="PUT" url="http://s3.amazonaws.com//#bucketName#/#filekey#" timeout="#HTTPtimeout#">
  <cfhttpparam type="header" name="Authorization" value="AWS aws-key:#signature#">
  <cfhttpparam type="header" name="Content-Type" value="#contentType#">
  <cfhttpparam type="header" name="Date" value="#dateTimeString#">
  <cfhttpparam type="header" name="x-amz-acl" value="#acl#">
  <cfhttpparam type="header" name="x-amz-storage-class" value="#storageClass#">
  <cfhttpparam type="body" value="#binaryFileData#">
 </cfhttp>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Tags:

Share:

Related posts