Signing AWS requests with signature version 4 in Swift 3

Here is the full source code I used for this post:

If you want to add more headers into your request (such as a JWT or other token) you will add them underneath line 125. The URLRequestSigner will take care of the rest because it automatically adds all headers needed to the signature.

In order to sign a request to AWS there are several steps which I followed.

The first is arranging the contents of the request into a standard format that Amazon has defined. In Swift it looks like this:

let canonicalRequestHash = [
url.query ?? "",
headers.map{ $0.key.lowercased() + ":" + $0.value }.sorted().joined(separator: "\n"),
].joined(separator: "\n").sha256()

Here I am taking the pieces of the request and adding them to a newline-separated string. A few things to note: Signed headers is a list of all the alphabetically sorted lowercased header keys separated by semi-colons. The body of the request must be hashed when it is put into the canonical request string.

The next thing to do is create the string to sign. This is a combination of the canonicalRequestHash as well as the type of hash that is being done, the dateTime (in ISO-8601 format), and the credential scope. All of these things are added into the stringToSign which is also separated by newlines.

let stringToSign = [
hmacShaTypeString, //AWS4-HMAC-SHA256
].joined(separator: "\n")

Now use this stringToSign to create an HMAC. The hex-string representation of this HMAC will be the signature for the request. This process can be seen above in the function called ‘hmacStringToSign’.

The final step is to add the signature to the Authorization header along with the credential scope and signed headers.

If you have any further questions, a good place to begin looking is on Amazon’s site where they define the AWS4 spec.

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store