MeV MeV - 14 days ago 10
PHP Question

AWS4 Signature key - is this tutorial wrong?

According to this page: Examples of How to Derive a Signing Key for Signature Version 4

The result of this code:

$kSecret = "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY";

$kDate = hash_hmac('sha256', "20120215", "AWS4" . $kSecret);
echo "date: " . $kDate . "<br>";

$kRegion = hash_hmac('sha256', "us-east-1", $kDate);
echo "region: " . $kRegion . "<br>";

$kService = hash_hmac('sha256', "iam", $kRegion);
echo "service: " . $kService . "<br>";

$kSigning = hash_hmac('sha256', "aws4_request", $kService);
echo "signing: " . $kSigning . "<br>";


should print:

kDate = '969fbb94feb542b71ede6f87fe4d5fa29c789342b0f407474670f0c2489e0a0d'

kRegion = '69daa0209cd9c5ff5c8ced464a696fd4252e981430b10e3d3fd8e2f197d7a70c'

kService = 'f72cfd46f26bc4643f06a11eabb6c0ba18780c19a8da0c31ace671265e3c87fa'

kSigning = 'f4780e2d9f65fa895f9c67b32ce1baf0b0d8a43505a000a1a9e090d414db404d'


So, kDate I get is correct. kRegion is not correct as I get the value:

a59e30f9d899c47b3dd68ea1c0ab3bb529e03a8f4ed2f54cb64af547330a22a0


I have tried using this website to calculate the HMAC (hmac generator) and I get the same result.

enter image description here

I really wonder if the page is wrong. Can anyone explain if it's my fault or AWS fault?

Thank you

Answer
  1. You should understand the values are binary and printed in hexadecimal form
  2. You are passing date in hexadecimal. You should convert it to binary and pass it before calling hash_hmac. Or store it in binary and print the same in hexadecimal
  3. You never mentioned the language you are using. I had to google to find out what language you are using. In PHP, you can pass: $raw_output = true to get the binary string
  4. Store the strings n binary and convert them to hex before printing.

Since I am not familiar with PHP, I tried the same in Python and the output matched the expected output. See how I convert it to hex and print.

import hmac
import hashlib
from base64 import b16encode as b16

def sign(key, msg):
    return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest()

def getSignatureKey(key, dateStamp, regionName, serviceName):
    kDate = sign(("AWS4" + key).encode("utf-8"), dateStamp)
    print b16(kDate)
    kRegion = sign(kDate, regionName)
    print b16(kRegion)
    kService = sign(kRegion, serviceName)
    print b16(kService)
    kSigning = sign(kService, "aws4_request")
    print b16(kSigning)
    return kSigning

key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY'
dateStamp = '20120215'
regionName = 'us-east-1'
serviceName = 'iam'

getSignatureKey(key, dateStamp, regionName, serviceName)

Output

969FBB94FEB542B71EDE6F87FE4D5FA29C789342B0F407474670F0C2489E0A0D
69DAA0209CD9C5FF5C8CED464A696FD4252E981430B10E3D3FD8E2F197D7A70C
F72CFD46F26BC4643F06A11EABB6C0BA18780C19A8DA0C31ACE671265E3C87FA
F4780E2D9F65FA895F9C67B32CE1BAF0B0D8A43505A000A1A9E090D414DB404D

PHP

string hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = false ] )