Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

thoresuenert's avatar

Unable to calculate golang binary hmac hash

Hello, i try to verify a request from messagebird service. https://developers.messagebird.com/docs/verify-http-requests

there pseudo code:

signature = HMAC_SHA_256(
        TIMESTAMP + \n + QUERY_PARAMS + \n + SHA_256_SUM(BODY),
        signing_key
)

if HMAC_EQUALS(signature, BASE_64_DECODE(request_signature)) {
    // Yay!
}

Go example

func sign(timestamp, queryParams string, body []byte, key string) []byte {
    var buf bytes.Buffer

    buf.WriteString(timestamp)
    buf.WriteRune('\n')
    buf.WriteString(queryParams)
    buf.WriteString('\n')

    hash := sha256.Sum256(body)
    buf.Write(hash[:])

    mac := hmac.New(sha256.New, []byte(key))
    mac.Write(buf.Bytes())

    return mac.Sum(nil)
}

actualSignature, err := base64.StdEncoding.DecodeString(reqSignature)
if err != nil {
    // handle error
}

signature := sign(timestamp, queryParams, body, signingKey)
if hmac.Equal(signature, expectedSignature) {
    // OK
}

the actualSignature includes a bytestring b"..."

i am not able to solve that.

my code so far, getting 404 all the time.

class MessageBirdController extends Controller
{
    public function update(Request $request)
    {
        $signature = base64_decode($request->header('MessageBird-Signature'));
        $time = $request->header('MessageBird-Request-Timestamp');
        $query = $request->getQueryString();
        $body_hash = hash('sha256', $request->getContent()); // is empty body

        $content = $time. '\n'. $query . '\n' . $body_hash;

        $expected = hash_hmac('sha256', $content , config('services.messagebird.secret'),true);
   
        if (! hash_equals($expected, $signature) ) {
            return response('',404);
        }

        return response();
    }
}
0 likes
0 replies

Please or to participate in this conversation.