Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate Pusher authentication string from Bash?

Tags:

bash

curl

pusher

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
like image 306
Adam Laughlin Avatar asked Nov 19 '25 22:11

Adam Laughlin


2 Answers

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
like image 75
mklement0 Avatar answered Nov 21 '25 23:11

mklement0


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.

like image 25
fagiani Avatar answered Nov 21 '25 23:11

fagiani



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!