AudioHook http signature

Hi
I have integrated the AudioHook API and i want to use the Http Message Signature that is offered. I have implemented it using the documentation linked to from the AudioHook documentation. I am using ngrok to tunnel the connection to my developer machine and this works well. The drawback of this is that some of the Http headers and components are different when the request reaches my PC. It is hard to verify the http signature, because of the affected http components. But i guess, that only some of the components, like @request-target and @authority is different from the original request to the ngrok service. So my plan was to fill those in manually before verifying and then all would be good. This is not the case, so i would like if i could get an example of the signature-base that i need to match to get a successful validation.

Hi Jacob,

The protocol specification contains an example signature in the Establishing Connection section (https://developer.genesys.cloud/devapps/audiohook/session-walkthrough#establishing-connection). You can use that at least a first "sanity check" of your signature verification code. I believe ngrok has an option to preserve the host header field, have you tried that?
Let me know if you can't get it to work. I can provide some sample code.

Thanks,
--Felix

hi Felix
yes. I have been using that documentation for my implementation. I am not sure how to sanity check the verification code. For that, wouldn't i need the signature-base, to see what was signed. My approach is to try to recreate the signature-base. Sign that and compare my signature with the signature received by the request.
About ngrok. to make it work so that AudioHook could connect to my developer pc without a certificate and without a public accessable address, i had to run it the following way:
ngrok http 8100 --host-header="localhost:8100"
Keeping the host header would fail with bad gateway. the localhost:8100 would then be the service that i was debugging.

Hi Felix,

Would it be possible to get the signature base that goes with the example from the "Establishing Connection" section? It would be greatly appreciated.

Thanks,

Hi Felix,

I'm also facing the same issue regarding http signature verification.
Could you provide the reference code to verify the http signature sent by AudioHook.

Best regards,

I found, possibly a problem with the way the signature is created by AudioHook.
If i specify a connection Uri with no path elements, like wss://this.that.dk. Then it seem that the AudioHook is generating the signature using no path element. According to rfc7230 Hypertext Transfer Protocol section 5.3.1. If the path element is empty, an '/' must be specified.

This means when i try to validate the @request-target with the '/' on my end. The validation fails because the AudioHook client generates the signature with an empty @request-target.

If i specify a connection Uri with path elements, like wss://this.that.dk/hello then the verification works as expected.

Hi Jakob,

Thank you for the information.

Actually I'm still trying to verify the signature.
I made the sample python code like below.

import base64
import hashlib
import hmac

signature_in_header = b'NZBwyBHRRyRoeLqy1IzOa9VYBuI8TgMFt2GRDkDuJh4='
private_key = 'TXlTdXBlclNlY3JldEtleVRlbGxOby0xITJAMyM0JDU='

signature_base = '''\
"@request-target": /api/v1/voicebiometrics/ws
"@authority": audiohook.example.com
"audiohook-organization-id": d7934305-0972-4844-938e-9060eef73d05
"audiohook-session-id": e160e428-53e2-487c-977d-96989bf5c99d
"audiohook-correlation-id": 30b0e395-84d3-4570-ac13-9a62d8f514c0
"x-api-key": SGVsbG8sIEkgYW0gdGhlIEFQSSBrZXkh
"@signature-params": ("@request-target" "@authority" "audiohook-organization-id" \
"audiohook-session-id" "audiohook-correlation-id" "x-api-key");keyid="SGVsbG8sIEkgYW0gdGhlIEFQSSBrZXkh";\
nonce="VGhpc0lzQVVuaXF1ZU5vbmNl";alg="hmac-sha256";created=1641013200;expires=3282026430\
'''

signature = hmac.new(base64.b64decode(private_key), signature_base.encode(), hashlib.sha256)
print("signature in header = {0}".format(signature_in_header))
print("signature = {0}".format(base64.b64encode(signature.digest())))
assert signature_in_header == base64.b64encode(signature.digest())

The information used in the signature base was brought from Audiohook Specification.
In the reference, the signature is NZBwyBHRRyRoeLqy1IzOa9VYBuI8TgMFt2GRDkDuJh4=.
But the generated signature in the code is YIjP15XG65XaP9WD0RhEvvx9qglhFCqSCtVqDUEw3LU=.

Are there any issues especially in the signature base and the code that makes signature?

Thank you

Hi Jakob,

Sorry to bother you many times.
I'm going to make a new post about signature base.

Thank you

i think you need a / in the end so it looks like this:
"@request-target": /api/v1/voicebiometrics/ws/

Hi,

Thank you for your advice.
I generated the new signature but It didn't match.
the new signature was "kd8V1MnXxwWfW8UTKsYeVnwJpK8r/zkgzOqNqo7yJcA=" .
I thought my code is wrong. Does it look OK?

not sure but this is what i did in C#:
public static string Signby_hmac_sha256(string secret, string stringToSign)
{
using (var hmacsha256 = new HMACSHA256(Convert.FromBase64String(secret)))
{
var bytes = Encoding.ASCII.GetBytes(stringToSign);
var hashedBytes = hmacsha256.ComputeHash(bytes);
return Convert.ToBase64String(hashedBytes);
}
}

Thank you for sharing your code.
It looks almost the same.

Hi Jakob,

I generated the signature base from the actual http header received from AudioHook and made the signature from it.
Now I finally got the same string with the one in the http header. I should have done the test using the actual header.
I really appreciate your help.

Thank you.

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.