# Webhook Signature Validation Issue Python

**URL:** <https://community.sendbird.com/t/webhook-signature-validation-issue-python/2423>\
**Category:** API\
**Created:** [June 8, 2021, 10:29am UTC](https://community.sendbird.com/t/webhook-signature-validation-issue-python/2423 "2021-06-08T10:29:19Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Vijay](https://avatars.discourse-cdn.com/v4/letter/v/4bbf92/32.png) [@Vijay](https://community.sendbird.com/u/Vijay)\
**Post date:** [June 8, 2021, 10:29am UTC](https://community.sendbird.com/t/webhook-signature-validation-issue-python/2423/1 "2021-06-08T10:29:19Z")

</div>

I am trying to verify the x-sendbird-signature in a webhook request using python. I have followed the documentation but signature I am generating is different from what I have received via webhook.

Webhook Header  
POST /inspect/01f7mzz7ecbqjtb983h25g1rsy HTTP/1.1  
[requestinspector.com](http://requestinspector.com)  
Accept: _/_  
X-Datadog-Trace-Id: 5337463762656296860  
Cf-Request-Id: 0a8ba40da800005229e182e000000001  
Content-Type: application/json  
X-Datadog-Sampling-Priority: 1  
User-Agent: SendBird  
Content-Length: 374  
Accept-Encoding: gzip  
X-Sendbird-Signature: 433d4a0877c86f0faf53a980ce8666bb65b8f308af2cb799eab40bfc72c64c24  
X-Signature: 433d4a0877c86f0faf53a980ce8666bb65b8f308af2cb799eab40bfc72c64c24  
X-Datadog-Parent-Id: 7172508198697502604  
Unicode-Escaped: true

Response Body:  
{“category”:“open\_channel:create”,“created\_at”:1623129257000,“operators”:,“app\_id”:“3CF528A5-523E-4E6B-9CA0-749360D6853E”,“channel”:{“is\_super”:false,“is\_distinct”:false,“name”:“testing-channel2”,“custom\_type”:"",“is\_ephemeral”:false,“data”:"",“channel\_url”:“sendbird\_open\_channel\_11554\_8f2c89dae26ef3a19da04a06ec89a4cf98cda99f”,“is\_discoverable”:false,“is\_public”:false}}

Here is my code  
body = {“category”:“open\_channel:create”,“created\_at”:1623129257000,“operators”:,“app\_id”:“3CF528A5-523E-4E6B-9CA0-749360D6853E”,“channel”:{“is\_super”:false,“is\_distinct”:false,“name”:“testing-channel2”,“custom\_type”:"",“is\_ephemeral”:false,“data”:"",“channel\_url”:“sendbird\_open\_channel\_11554\_8f2c89dae26ef3a19da04a06ec89a4cf98cda99f”,“is\_discoverable”:false,“is\_public”:false}}

def validate\_signature(request: Request, body):  
key = bytes(api\_token, ‘utf-8’)  
incoming\_signature = request.headers.get(‘x-sendbird-signature’)  
signature\_to\_compare = hmac.new(  
key=key,  
msg=bytes(str(body).encode(‘utf8’)),  
digestmod=hashlib.sha256).hexdigest()

```
assert incoming_signature == signature_to_compare

```

incoming\_signature = ‘433d4a0877c86f0faf53a980ce8666bb65b8f308af2cb799eab40bfc72c64c24’  
signature\_to\_compare =‘6c9efbdd5db48c90634d6a08cb799f91d40d9bda372ea22602a62f65b0a1b824’

Key : b’19217214545b6393ae767de3454b4f9b2167eed1’

I tried various suggestions but with no help.

Thanks in Advance

---

<div class="post-metadata">

**Author:** ![Tyler](https://sea2.discourse-cdn.com/flex020/user_avatar/community.sendbird.com/tyler/32/810_2.png) [@Tyler](https://community.sendbird.com/u/Tyler)\
**Post date:** [June 8, 2021, 2:55pm UTC](https://community.sendbird.com/t/webhook-signature-validation-issue-python/2423/2 "2021-06-08T14:55:30Z")

</div>

Hi @Vijay,

Are you comparing the body as JSON or a string? It’s anticipated that you receive the body as a string, and do not convert it to JSON until after it’s been validated.

---

<div class="post-metadata">

**Author:** ![Vijay](https://avatars.discourse-cdn.com/v4/letter/v/4bbf92/32.png) [@Vijay](https://community.sendbird.com/u/Vijay)\
**Post date:** [June 8, 2021, 4:21pm UTC](https://community.sendbird.com/t/webhook-signature-validation-issue-python/2423/4 "2021-06-08T16:21:22Z")

</div>

@Tyler Thanks for the quick response and help. Issue got resolved.

---

<div class="post-metadata">

**Author:** ![Tyler](https://sea2.discourse-cdn.com/flex020/user_avatar/community.sendbird.com/tyler/32/810_2.png) [@Tyler](https://community.sendbird.com/u/Tyler)\
**Post date:** [June 8, 2021, 4:22pm UTC](https://community.sendbird.com/t/webhook-signature-validation-issue-python/2423/5 "2021-06-08T16:22:00Z")

</div>

Glad to hear that! Was the issue that the body was being converted prior to signature validation?

---

<div class="post-metadata">

**Author:** ![Vijay](https://avatars.discourse-cdn.com/v4/letter/v/4bbf92/32.png) [@Vijay](https://community.sendbird.com/u/Vijay)\
**Post date:** [June 8, 2021, 5:12pm UTC](https://community.sendbird.com/t/webhook-signature-validation-issue-python/2423/6 "2021-06-08T17:12:58Z")

</div>

Yeah so I was storing body as a json and while signature generation I was converting it back to string.

---

<div class="post-metadata">

**Author:** ![Tyler](https://sea2.discourse-cdn.com/flex020/user_avatar/community.sendbird.com/tyler/32/810_2.png) [@Tyler](https://community.sendbird.com/u/Tyler)\
**Post date:** [June 8, 2021, 6:07pm UTC](https://community.sendbird.com/t/webhook-signature-validation-issue-python/2423/7 "2021-06-08T18:07:31Z")

</div>

Makes sense! Glad it was able to be quickly fixed.

---

<div class="post-metadata">

**Author:** ![Aanal\_Shah](https://sea2.discourse-cdn.com/flex020/user_avatar/community.sendbird.com/aanal_shah/32/4661_2.png) [@Aanal\_Shah](https://community.sendbird.com/u/Aanal_Shah)\
**Post date:** [January 15, 2024, 6:30am UTC](https://community.sendbird.com/t/webhook-signature-validation-issue-python/2423/8 "2024-01-15T06:30:25Z")

</div>

I am trying to verify the x-sendbird-signature in a webhook request using python. I have followed the documentation but signature I am generating is different from what I have received via webhook. This is the code that I have written for signature generation and comparison.

```auto
request_body = {
  'category': 'group_channel:message_read',
  'app_id': '',
  'channel': {
    'channel_url': '',
    'name': '',
    'data': '',
    'custom_type': 'SENDBIRD_DESK_CHANNEL_CUSTOM_TYPE',
    'is_distinct': False,
    'is_super': False,
    'is_public': False,
    'is_discoverable': False,
    'is_ephemeral': False,
    'type': 'group'
  },
  'read_updates': [
    {
      'user_id': '',
      'read_ts': 1705299189687,
      'channel_unread_message_count': 0,
      'total_unread_message_count': 2
    }
  ],
  'members': [
    {
      'user_id': '',
      'nickname': '',
      'profile_url': 'https://templates.joomla-monster.com/joomla30/jm-news-portal/components/com_djclassifieds/assets/images/default_profile.png',
      'metadata': {
        
      },
      'is_online': True,
      'push_enabled': True,
      'push_trigger_option': 'default',
      'unread_message_count': 2,
      'total_unread_message_count': 2,
      'channel_unread_message_count': 0,
      'channel_mention_count': 0,
      'state': 'joined',
      'is_active': True,
      'is_hidden': 0
    }
  ]
}

x_sendbird_signature = request.META.get('HTTP_X_SENDBIRD_SIGNATURE')
api_token = bytes(sendbird_api_key, 'utf‐8')
http_request_body = bytes(str(request_body), 'utf‐8')
signature_to_compare = hmac.new(
    key=api_token,
    msg=http_request_body,
    digestmod=hashlib.sha256).hexdigest()

```

**x\_sendbird\_signature** that we got from request c960b45a060aff9ce2e9dd1d37709aca6de358c135b2f7b7fb35539ee2ee60f0

**signature\_to\_compare** generated from code e5ca33322459ec24348a24a749f849ab5315ba2d7ee63c7fdfa469333cee0009

I tried with various changes but didn’t work for me.

Any suggestions?

Thanks In Advance.

We are using Python 3.12.1 and Django==4.2.7

---

<div class="post-metadata">

**Author:** ![Tyler](https://sea2.discourse-cdn.com/flex020/user_avatar/community.sendbird.com/tyler/32/810_2.png) [@Tyler](https://community.sendbird.com/u/Tyler)\
**Post date:** [January 16, 2024, 9:49am UTC](https://community.sendbird.com/t/webhook-signature-validation-issue-python/2423/9 "2024-01-16T09:49:24Z")

</div>

@Aanal_Shah,

Welcome to the Sendbird community.

It looks like the issue is that you’re modifying the body by converting it to a string, then to a bytes object.

The body should be as bytes or a string. You’re converting it from, what I assume is JSON, to a string and then to bytes. I wrote a quick demo in flask that works.

```auto
import hashlib
import hmac

from flask import Flask, jsonify, request

api_token = b'my_applicaton_token';

app = Flask( __name__ )
@app.route('/webhook', methods=['POST'])
def webhook_receiver():
  data = request.get_data()
  signature_header = request.headers.get('x-sendbird-signature')
  compare_signatures(signature_header, data)
  return jsonify({'message': 'Webhook received successfully'}), 200

def compare_signatures(signature, message):
  signature_to_compare = hmac.new(key=api_token, msg=message, digestmod=hashlib.sha256).hexdigest()
  print(signature_to_compare == signature)

if __name__ == ' __main__':
    app.run(debug=True, port=8000)

```

Here is a video showing the outcome of the comparison

---

<div class="post-metadata">

**Author:** ![Aanal\_Shah](https://sea2.discourse-cdn.com/flex020/user_avatar/community.sendbird.com/aanal_shah/32/4661_2.png) [@Aanal\_Shah](https://community.sendbird.com/u/Aanal_Shah)\
**Post date:** [January 16, 2024, 1:40pm UTC](https://community.sendbird.com/t/webhook-signature-validation-issue-python/2423/10 "2024-01-16T13:40:08Z")

</div>

Thank you for your quick reply. I resolved my issue as per your guidance.
