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
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>
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>