Verifying Signature Mismatch Python and I dont know why

I am trying to verify the signature of a subscription I created. The signature I am generating is not the same as the expected signature. I don’t know what I’m doing wrong.

Edit: I’m pretty sure the problem is coming from how I’m getting the body data and then processing it but I’m not sure how I should go about doing that.

using python 3.8.10

from flask import Flask
from threading import Thread
from flask import request
import os
import hmac
import hashlib
import requests
@app.route('/webhooks/callback', methods=['POST'])
def process_twitch():
  message_id = request.headers['Twitch-Eventsub-Message-Id']
  message_timestamp = request.headers['Twitch-Eventsub-Message-Timestamp']
  print('message timestamp ' + message_timestamp)
  #body = str(request.get_data()) this also works but doesn't match
  body = str(request.get_json())
  message_signature = request.headers['Twitch-Eventsub-Message-Signature']
  is_valid = verify_signature(message_id, message_timestamp, body, message_signature)
  print(is_valid)

  if (not is_valid):
    response = app.response_class(
          response="",
          status=403,
          mimetype='application/json'
      )
    return response
  if (is_valid):
    challenge = request.form['challenge']
    response = app.response_class(
          response=challenge,
          status=200,
          mimetype='application/json'
      )
    return response
def verify_signature(message_id, message_timestamp, body, message_signature):
  #print(body)
  hmac_message = message_id + message_timestamp + body
  print(hmac_message)
  secret = os.environ['Webhook_Secret']
  key = bytes(secret, 'utf-8')
  #key = secret.encode()
  data = bytes(hmac_message, 'utf-8')
  #data = hmac_message.encode()
  signature = hmac.new(key, data, hashlib.sha256)
  expected_signature_header = 'sha256=' + signature.hexdigest()
  print(message_signature)
  print(expected_signature_header)

  if  message_signature != expected_signature_header:
    return False
  return True
1 Like

I found the solution :smiley:

I needed to return the request.get_data() as a string and not as bytes.

body = request.get_data(True, True, False)
1 Like

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