3

I'm having trouble generating the "right" authentication string to use when sending a message to Pusher via curl

Here's my script, the secret bits cut out of course:

#!/bin/bash

key="my_key"
secret="my_secret"
appID="my_app_id"

timestamp=`date +%s`
data='{"name":"say_stuff","channel":"test","data":"{\"message\":\"oh_yeah\"}"}'
md5data=`echo "$data" | md5`
authSig=`echo 'POST\n/apps/"$appID"/events\nauth_key="$key"&auth_timestamp="$timestamp"&auth_version=1.0&body_md5="$md5data"' | openssl dgst -sha256 -hex -hmac "$secret"`

curl -H "Content-Type:application/json" -d "$data" "http://api.pusherapp.com/apps/$appID/events?body_md5=$md5data&auth_version=1.0&auth_key=$key&auth_timestamp=$timestamp&auth_signature=$authSig"

The authSig is certainly generated, and looks like valid HmacSHA256Hex

However, when it runs the curl command, I get this response:

Invalid signature: you should have sent HmacSHA256Hex("POST\n/apps/$appID/events\nauth_key=$key&auth_timestamp=1432086733&auth_version=1.0&body_md5=e5997a811232ffae050be74242254ceb", your_secret_key), but you sent "55029a5e2d1058b352b5c22709e7fb9cb0c6f147846ed09dbc6bcaf6a7a804c7"

Is it possible that the openssl utility on my machine (Mac OS X 10.10) is somehow different than Pusher's?

Here's something funny I've noticed now. If you go here:

https://pusher.com/docs/rest_api

And scroll down to "Worked authentication example" you'll be able to follow along with an example.

I've tried generating the signature using the example by running:

echo 'POST\n/apps/3/events\nauth_key=278d425bdf160c739803&auth_timestamp=1353088179&auth_version=1.0&body_md5=ec365a775a4cd0599faeb73354201b6f' | openssl dgst -sha256 -hex -hmac 7ad3773142a6692b25b8

and I get

aa368756587116f3997427fe1b315ed0e2f2faa555066e565a25cfe6f47c9396

as opposed to their example which results in

da454824c97ba181a32ccc17a72625ba02771f50b50e1e7430e47a1f3f457e6c
5
  • It may or may not be the cause of your problems, but you should double-quote all variable references to protect them from unintended shell expansions (interpretation by the shell); "$data", instead of $data, "$secret" instead of $secret, ... Commented May 20, 2015 at 2:31
  • Tried that, same problem... Commented May 20, 2015 at 2:37
  • Got it; please add the double quotes to your question, so as not to create a distraction. Commented May 20, 2015 at 2:38
  • Thanks for the update, but I meant: double-quote variable reference unless they're already inside a (larger) double-quoted string. Commented May 20, 2015 at 2:41
  • Sorry about that! Wasn't aware of that potential issue. Still broken though... Commented May 20, 2015 at 3:20

2 Answers 2

3

Try the following:

#!/bin/bash

key="my_key"
secret="my_secret"
appID="my_app_id"

timestamp=$(date +%s)
data='{"name":"say_stuff","channel":"test","data":"{\"message\":\"oh_yeah\"}"}'
# Be sure to use `printf %s` to prevent a trailing \n from being added to the data.
md5data=$(printf '%s' "$data" | md5)

path="/apps/${appID}/events"
queryString="auth_key=${key}&auth_timestamp=${timestamp}&auth_version=1.0&body_md5=${md5data}"

# Be sure to use a multi-line, double quoted string that doesn't end in \n as 
# input for the SHA-256 HMAC.
authSig=$(printf '%s' "POST
$path
$queryString" | openssl dgst -sha256 -hex -hmac "$secret")

curl -H "Content-Type:application/json" -d "$data" "http://api.pusherapp.com${path}?${queryString}&auth_signature=${authSig}"

There were several problems with your code:

  • By using echo you appended a trailing newline to the input fed to md5 and openssl, which altered the data.
  • The \n sequences in the string to pass to openssl are meant to represent actual newlines, whereas you used them as literals.

Also, I've de-duplicated the code, used ${name} variable references (names enclosed in curly braces) for better visual clarity, and I've also fixed the double-quoting problems.


Regarding the sample hash from the website: again, your problems were using echo and not expanding the embedded \n sequences to actual newlines; the following shell command does give the correct result:

# Expand the '\n' sequences to newlines using an ANSI C-quoted string
# ($'...')
s=$'POST\n/apps/3/events\nauth_key=278d425bdf160c739803&auth_timestamp=1353088179&auth_version=1.0&body_md5=ec365a775a4cd0599faeb73354201b6f'
# Pass to openssl using `printf %s`.
printf %s "$s" | openssl dgst -sha256 -hex -hmac 7ad3773142a6692b25b8
Sign up to request clarification or add additional context in comments.

2 Comments

I'm glad to hear it; string handling in the shell is tricky business.
I have the same question for VBscript, if you're interested: stackoverflow.com/questions/38962360/…
1

It has been a while but I recently needed this and the script below worked for me:

#!/bin/bash

# Replace the following placeholders
PUSHER_AUTH_KEY='<your-auth-key>'
PUSHER_AUTH_SECRET='<your-secret-key>'
PUSHER_URL_PREFIX='https://api-<your-cluster>.pusher.com'
PUSHER_URL_SUFFIX='/apps/<your-app-id>/events'
PUSHER_DATA='{"data":"{\"message\":\"hello world\"}","name":"my-event","channel":"my-channel"}'

# From here on it should be mostly standard
PUSHER_AUTH_VERSION='1.0'
PUSHER_AUTH_TIMESTAMP=$(date +%s)
PUSHER_URL=$PUSHER_URL_PREFIX$PUSHER_URL_SUFFIX
PUSHER_BODY_MD5=$(echo -n $PUSHER_DATA | openssl dgst -md5 -hex)
PUSHER_SIGNATURE="POST\n$PUSHER_URL_SUFFIX\nauth_key=$PUSHER_AUTH_KEY&auth_timestamp=$PUSHER_AUTH_TIMESTAMP&auth_version=$PUSHER_AUTH_VERSION&body_md5=$PUSHER_BODY_MD5"
PUSHER_AUTH_SIGNATURE=$(echo -en $PUSHER_SIGNATURE | openssl dgst -sha256 -hex -hmac $PUSHER_AUTH_SECRET)

curl -i -H 'Content-Type: application/json' -d "$PUSHER_DATA" \
"$PUSHER_URL?"\
"body_md5=$PUSHER_BODY_MD5&"\
"auth_version=$PUSHER_AUTH_VERSION&"\
"auth_key=$PUSHER_AUTH_KEY&"\
"auth_timestamp=$PUSHER_AUTH_TIMESTAMP&"\
"auth_signature=$PUSHER_AUTH_SIGNATURE"

It's very basic, using the sample data on the Pusher website but it can be improved to receive some of the parameters as inputs based on your use case. The goal here is that you can have a general idea of how it works.

Please do notice that openssl must be installed in order to work.

Hopefully this will become useful to others in the future.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.