Wowza Community

Can't get the hmac authentication to work

Hi Folks,

I’ve been fiddling for a week now, and I can’t seem to get the hmac authentication to work. I’ve been using the API with the simple api/access keys in the request, which was fine for testing purposes. Now I’d like to move to hmac authentication for the next level, but I always get a 401 http response:

status: 
401
code: 
"ERR-401-InvalidSignature"
title: 
"Invalid Signature Error"
message: 
"Invalid signature."
description: 
""

I just don’t get what’s wrong and the wowza help is limited as I’m doing this in JavaScript and no example is provided. I can only figure out so much from the 2 examples provided on that page, but I’m doing something wrong it seems:

HMAC authentication https://www.wowza.com/docs/how-to-use-the-wowza-streaming-cloud-rest-api#hmac-authentication

This is the last current code I have, but I’ve tried a myriad of things:

import hmacSHA256 from 'crypto-js/hmac-sha256';
import Base64 from 'crypto-js/enc-base64';
export async function generateRequestSignature(requestPath, APIKey, timestamp) {    

...

    return Base64.stringify(hmacSHA256(timestamp.getTime() + ":" + formatedRequestPath + ":" + APIKey, APIKey));
}

requestPath contains “/api/v1.5/live_streams”

timestamp contains a value like 1593156737456

APIkey also contains the correct key.

What am I missing?

Which key has to be included in the http header exactly? I assume not the API key, right?

I find it difficult to understand from the help article to identify exactly which of the API key and Access key is to be used to encrypt and/or sent along with the http header.

I assume then that the API key is the so called Public key and is sent along in the header, and the Access key is the so called private key which is not sent along in the header?

If so, why is the access key not involved in the signature generation in the first place?

It’s somewhat confused in my mind :slight_smile:

Thanks for the help !

Hi @Fabrice Baugniet is this related at all to your current support ticket 361086 where we sent you a download that resolved an issue for you? Or is this a different issue?

I’m assuming you followed this article?

https://www.wowza.com/docs/how-to-use-the-wowza-streaming-cloud-rest-api#hmac-authentication

You can respond to your current ticket if you’d like to ask your assigned engineer.

Hi :slight_smile: No this is totally unrelated, a different issue. You assume right: Of course I did follow your article, as stated in my question. I also refer to this article in my question, but I see that it didn’t take this as a link apparently.

Anyway, I’m not been able to get it to work with the mentioned article unfortunately.

I have this working in Postman, couple of things to note.

In your headers, only pass your wsc-access-key not your wsc-api-key. Passing your wsc-api-key defeats the purpose of this exercise. Additionally in your headers, you need wsc-timestamp and wsc-signature. wsc-timestamp should be a Unix epoch. You can calculate that as follows and set in Postman -

// get and set a timestamp in seconds (Unix epoch)
var timestamp = Math.floor(Date.now() / 1000);
pm.variables.set("wsc-timestamp", timestamp);
console.log("timestamp=" + timestamp);

This is not equivalent to built-in timestamp in Postman/JS so I’m going to do more digging here.

The other item to check is around computing the HMAC signature. I noticed the Ruby parameters feel flipped or backwards to me so here is how they are working in JS -

// compute signature
var signature = CryptoJS.HmacSHA256(data, apikey).toString();
console.log("signature=" + signature);

Full gist here - https://gist.github.com/akeller/265377d9f317e7665cc96b522189a80a

I’ll look to get a plain JS version as an example and work with our tech writers to make those instructions a little easier to follow too.

Are you including the key and timestamp in the headers as well as the signature?

I’ll see if I can get a good working example together for you today.

I’ll also add this to our list of documentation and example feature requests to include more JS based example code. It’s been on my list, but this looks like it could be a quick hit.

fetch(requestPath, {
                    "method": "POST",
                    "headers": {
                        "wsc-api-key": APIKey,
                        "wsc-access-key": accessKey,
                        "wsc-timestamp": requestTimestamp.getTime(),
                        "wsc-signature": requestSignature,
                        "Content-Type": "application/json"
                    },
                    "body": data
                })

I just tried by including both keys (the timestamp was already included, forgot to answer your question on that one). But same result: 401 unauthorised - invalid signature.

The timestamp value comes from the same variable that passes it to the signature generation function, so these values are identical.

Anyway, it doesn’t make sense to me that both keys should be passed in the header, as this is what the header request looked like before trying to use the hmac authentication, or am I wrong?

That did it, thanks Amara!

Fantastic! Thanks for marking this as accepted too Fabrice!