Hmac authentication issue


#1

I’m trying to validate hmac authentication for my api set. Below are the issue details I’m facing.
Setup :

  1. I have enabled “HMAC (Signed Auth key)” for my api set in authentication dropdowns.

  2. I’m passing authrization header as below.
    Signature keyId=<key_value>,algorithm=“hmac-sha1”,headers="(request-target) Date hmac-text",signature="${url_encoded_signature}"

  3. I have added header Date and hmac-text
    The above header values are used for deriving the signature value.

  4. For deriving the signature I have used the below shell script.
    function urlencode() {
    echo -n “$1” | perl -MURI::Escape -ne ‘print uri_escape($_)’ | sed “s/%20/+/g”

}

date="$(LC_ALL=C date -u +"%a, %d %b %Y %X %Z")"
encoded_date=$(urlencode “${date}”)
signature=$(echo -n “date:${encoded_date}” | openssl sha1 -binary -hmac |base64)
url_encoded_signature=$(urlencode “${signature}”)

echo “date: $date”
echo “encoded date: $encoded_date”
echo “signature: $signature”
echo “url_encoded_signature: $url_encoded_signature”

  1. With the above when send api request, below is the error I’m getting.
    “error”: “Authorization field missing, malformed or invalid”

  2. Gateway logs look like this.
    level=info msg=“API Requires HMAC signature, session missing HMACSecret or HMAC not enabled for key”
    level=error msg=“No HMAC secret for this key” error=“This key ID is invalid” keyID=<key_id>
    level=info msg=“Authorization field missing or malformed” origin=<origin_value> path=<api_path>

  3. If I lookup for the key id i’m using in keys,
    ‘Enforce HMAC request signing’ is not checked.
    And when I try to check and update it says
    “HMAC Secret
    No Key HMAC secret for this user, please generate a new key.”

Kindly help me in setting up the this authentication for my api set.
And I have referred to this issue and have used the same script


#2

Hi Ashwini,

How did you create the key used to authorise the requests?

Thanks,
Luan


#3

Hi Luan,
Its the same key, which was issued after requesting key to defined policy for my api set, from dev portal.


#4

Hi Ashwini,

We released a fix around HMAC secrets not displaying in the recent patch release: Tyk Gateway 2.5.1 and more

Can you confirm that the key you’re using has HMAC enabled via the dashboard?

Thanks,
Luan


#5

Hi Luan,
Thank you very much for the update.
I checked with updated version i.e…
dashboard 1.5.1
gateway 2.51.
hmac secret is visible in dashboard now.
But I’m getting the below logs.
level=error msg=“Date parsing failed” date_string=0001-01-01 00:00:00 +0000 UTC
level=error msg=“Clock skew outside of acceptable bounds”
level=info msg=“Authorization field missing or malformed” origin=<origin_ip> path=<api_path>

I have disabled clock skew.
Even then I’m getting this error. Please help me with this


#6

You will need to solve the date parsing issue first - ensure the date string is in the correct format (same as docs ideally)


#7

Hi Martin,
When I generate signature with the below script and pass it in authorization header,
I get the below error.

Script :
date="$(LC_ALL=C date -u +"%a, %d %b %Y %X %Z")"
encoded_date=$(echo -n $date | perl -MURI::Escape -ne ‘print uri_escape($)’ | sed “s/%20/+/g”)
signature=$(echo -n “date:${encoded_date}” | openssl sha1 -binary -hmac <hmac_secret> |base64)
url_encoded_signature=$(echo -n $signature | perl -MURI::Escape -ne 'print uri_escape($
)’ | sed “s/%20/+/g”)

echo “date: $date”
echo “encoded date: $encoded_date”
echo “signature: $signature”
echo “url_encoded_signature: $url_encoded_signature”

Error :
level=error msg=“Signature string does not match!” expected=“fbWcm7QCRGF3WyaY9ALGrT6J6KE%3D” got=“Mn7CPaP6TL5RB82zTA%2FUqSFb97E%3D”

and if I pass the expected signature from above log i.e… fbWcm7QCRGF3WyaY9ALGrT6J6KE%3D its working fine.
but I don’t find anything wrong in my script. Can you please point out if I’m doing something wrong in there.


#8

Here’s how we do it with just a date header, and here’s how we do it with multiple headers, these tests are based on the spec, so it might be something as simple as a newline.