Posters cont.

After spending weeks creating my own poster, I now find myself glancing more at walls looking for interesting posters. During one of my glances, I saw one that was extremely captivating and had good…

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




How to sign a URLRequest and download a file from S3 in iOS.

Let’s talk about downloading files from AWS S3 in iOS mobile Apps.

But what if we have some restrictions, don’t want to add AWSS3 to our project just to download once a single file or we need to have URLRequest and download something with it.

We have a few options in this case. The easiest one is to make a required file public in a bucket. Such file will be visible for all who have the correct link. But it’s not secure, and such approach very depends on our needs and type of content. Yes, we can still have a unique and ugly link, so nobody will just guess it. But better to use every possible solution to make content secure and make our user feel safe especially when we can get this just out from the AWS box.

Let’s create signed request to get a non-public image from our S3 bucket.
AWS uses Signature V4 so that we will use it. But old regions can still support Signature V2, if they were created until 10 Jan 2014, according to official documentation.

At the beginning we need S3. I propose to create it without help from Mobile Hub side. Just skip this section if you’re familiar with AWS and this process.

We need to select S3 service from the list of services.

Now we can create a new bucket for testing. Let’s call it downloadimagetestbucket. We can keep all settings by default for now.

We have storage, so let’s upload our test image. Keep all default settings for it, to be sure that it’s not public.

As before from AWS console with all services list select IAM. From “Users” tab we can add a new user.

A mythical person with name downloadimagetestuser and Programmatic access.

And then just next… next… next and create. Do not forget to save ID and secret.
We have the user without any permissions, and he can do nothing in our AWS. Absolutely useless person.

Let’s teach him some tricks. We need to add permission to access S3.

For that, we’ll create separate policy from the Policies tab.

We can play with a visual editor, but sometimes with JSON, it can be much faster. But in this case we should know what are we doing; otherwise it won’t work or even validated.

JSON looks like

Let’s name it downloadimagetestbucketpolicy. You can add some description too. And then create it. Now we should go back to our created useless user. Select it and in the permission tab select Add permissions.

Select Attach existing policies directly and filter by policy name. Attach the test policy to the user.

Now with this permission, we can use our user.

For creating a request, we will need

Some info from the official documentation.

The idea is pretty simple. We have some request. We calculate signature string from it using user’s secret and passing user’s ID with the request. AWS will use this ID to find the user and will use the same secret to calculate the signature. And then compare it with the signature from the request. Everything will be OK if it’s the same.

Signature depends on HTTP headers, so let’s add some before actual calculating of the signature.

The string contains access key ID and request scope.
Template (accessKeyID)/(requestScope)

Request scope contains

We will need the request scope for calculating the signature too.

Scope template (dateString)/(region)/(serviceName)/(terminator)

Full template (accessKeyID)/(dateString)/(reion)/(serviceName)/(terminator)

Should contain all headers which we use for calculating the signature.

We need all HTTP fields names from the request, sort them alphabetically in a case-insensitive way and enumerate them with semicolon separator. Headers should be lowercased. And we will use HTTP headers few times, and each time they should be sorted.

Template (header);(header)

Will looks like content-type;host;x-amz-content-sha256;x-amz-date

Each section should be with a new line \n

It contains

Final canonical request string for our test app will look like GET\n/downloadimagetestbucket/TestImage.png\n\ncontent-type:image/png\nhost:s3.us-east-1.amazonaws.com\nx-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\nx-amz-date:20181009T115731Z\n\ncontent-type;host;x-amz-content-sha256;x-amz-date\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

As for the canonical request, each section should be with a new line \n.

It contains

Template AWS4-HMAC-SHA256\n(dateStringISO8601)\n(requestScope)\n(hexEncodedSHA256CanonicalRequestString)

As we saw before AWS uses the HMAC-SHA256 algorithm, we can use the CommonCrypto framework or any third party solution to make our life a bit simpler.

Each next step is nested encryption of data with previously generated keys with HMAC-SHA256.

And that’s all. Now we have everything for Authorization HTTP header. We can download our file from S3.

Add a comment

Related posts:

What CEO Departures Say About the Economy

The past few months have seen CEOs departing companies at a record clip — faster than any point in the past 17 years. These include the embattled executives heading up WeWork and Juul, making it seem…

Work on yourself amidst the Depressing Coronavirus lockdown

As we step into week 2 of nation-wide lockdown in India. Most of us might have already realized that it’s going to be a long battle. There is no point in spending this time worrying. Let’s rather…

Ten Things

A list of things holding me down and keeping me sane. “Ten Things” is published by Nicole Brown in Writers’ Blokke.