6

I am designing a RESTful API in python. I want to use HMAC authentication. I could not find any suitable HMAC libraries, so I am rolling my own. However I want to use a well-known standard such as AWS HMAC authentication v4.

While coding an AWS-compliant client and server HMAC auth implementation, I noticed some uncommon aspects of the standard's design. I fail to fully grasp several design choices that were made.

Question 1: Why does AWS use a complex signing key (produced via HMAC) instead of the shared secret itself?

Task 3: Calculate the AWS Signature Version 4 describes:

Before you calculate a signature, you derive a signing key from your AWS secret access key. (You don't just use your secret access key to sign the request.) You then use the signing key and the string to sign that you created in Task 2: Create a String to Sign for Signature Version 4 as the inputs to a keyed hash function. The hex-encoded result from the keyed hash function is the signature.

To calculate a signature

Derive your signing key. To do this, you use your secret access key to create a series of hash-based message authentication codes (HMACs) as shown by the following pseudocode, where HMAC(key, data) represents an HMAC-SHA256 function that returns output in binary format. The result of each hash function becomes input for the next one.

Pseudocode for deriving a signing key:

kSecret = Your AWS Secret Access Key
kDate = HMAC("AWS4" + kSecret, Date)
kRegion = HMAC(kDate, Region)
kService = HMAC(kRegion, Service)
kSigning = HMAC(kService, "aws4_request")

Question 2: I do not understand the purpose of the 'credential scope' string.

In steps 2-3 of Task 2 (Create a String to Sign for Signature Version 4), a date and credential scope value are appended to the string that is signed. What is the purpose of these values?

The standard already signs the UTC timestamp in the x-amz-date header, as part of the canonical request that was prepared in Task 1. The same is true of the region specifier (us-east-1), since it should presumably be reflected in the Host: header.

Append the request date value, followed by a newline character. The date is specified by using the ISO8601 Basic format via the x-amz-date header in the YYYYMMDD'T'HHMMSS'Z' format. This value must match the value you used in any previous steps.

20110909T233600Z\n

Append the credential scope value, followed by a newline character. This value is a string that includes the date (just the date, not the date and time), the region you are targeting, the service you are requesting, and a termination string ("aws4_request") in lowercase characters. The region and service name strings must be UTF-8 encoded.

20110909/us-east-1/iam/aws4_request\n

The date must be in the YYYYMMDD format. Note that the date does not include a time value.

1 Answer 1

3

I could not find any suitable HMAC libraries

Err, the standard library has one. So does the cryptography library.

Question 1: Why does AWS use a complex signing key (produced via HMAC) instead of the shared secret itself?

One good reason I can see for doing it this way is to avoid a leaked signing key compromising the entire AWS account. Deriving a signing key from a combination of the secret key, region, a specific service and other values ensures that different things use different signing keys.

Question 2: I do not understand the purpose of the 'credential scope' string.

The "credential scope value" (20110909/us-east-1/iam/aws4_request\n) probably helps Amazon to assert that a particular request is targeted at the region and service. I don't see why the date is included so many times but it may have just been an oversight when Amazon is designing the process.

3
  • To clarify, I am currently using the python Hmac library. However the complexity came into play as I was determining which parts of the http request to sign and other important implementation details. Thanks for the clarification.
    – octagonC
    Commented Jan 4, 2015 at 10:27
  • Does the way means that AWS have to store my secret key in plain text instead of slat hash, in order to generates its own HMAC/sign key?
    – petertc
    Commented Aug 31, 2016 at 12:07
  • @okwap yes. Almost any time a symmetric key is needed, all parties need to have a clear copy of it.
    – kag0
    Commented Jan 26, 2017 at 22:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .