The client part is very easy:
#!/bin/bash
# server address (todo: add an option to set it on command line)
server=127.0.0.1
# private key
# you can generate one with: openssl genrsa -out rsa-test 2048
# public key can be obtained with: openssl rsa -pubout -in rsa-test
privkey="rsa-test"
# message is given on command line
message="$@"
# Message authentication code is a random number appended to unix EPOC
mac=$(bc <<<"$(date +%s)+$RANDOM")
data="$(base64 <<<"{ \"message\": \"$message\", \"mac\": $mac }")"
signature="$(openssl rsautl -sign -inkey $privkey -in <(echo "$data") |base64)"
wget -O - --post-data "data=$data&signature=$signature" http://$server
Notice that the signature process will fail if the message is too long. In that case, a hash of the message should be used instead of the message itself. We might then consider using dgst instead of rsautl.
I think the client should also send its public key, otherwise I don't know how the server can guess it
So basically, the last line should rather be:
wget -O - --post-data "data=$data&signature=$signature&pubkey=$(openssl rsa -pubout -in $privkey)" http://$server