Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using the X-Signature header with sha256 hash of message body #4321

Closed
9 tasks done
baylf2000 opened this issue Dec 22, 2021 · 1 comment
Closed
9 tasks done

Using the X-Signature header with sha256 hash of message body #4321

baylf2000 opened this issue Dec 22, 2021 · 1 comment
Labels
question Question or problem question-migrate

Comments

@baylf2000
Copy link

baylf2000 commented Dec 22, 2021

First Check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google "How to X in FastAPI" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to FastAPI but to Pydantic.
  • I already checked if it is not related to FastAPI but to Swagger UI.
  • I already checked if it is not related to FastAPI but to ReDoc.

Commit to Help

  • I commit to help with one of those options 👆

Example Code

from fastapi import FastAPI, Header, Request
from typing import Optional, Any, Dict, AnyStr, List, Union
from pydantic import BaseModel

import hmac
import hashlib
import binascii

my_secret = "dc3abf2ff68da30f758963a859e4b98d"
app = FastAPI()

def create_hash(key, message):
    hmac = hmac.new(key=my_secret.encode('utf-8'), msg=message.encode('utf-8), digestmod=hashlib.sha256)
    message_digest = hmac.hexdigest()
    return message_digest

@app.post("/api/message")
async def api_message(request: Request):

    xsig = request.headers.get("X-Signature")
    message_body = await request.json()
    message_string = str(message_body)

    my_hash = create_hash(my_secret, message_string)
    print ("my-new-x-sig: " + str(my_new_hash) + "\r\n")

Description

This isn't a problem with FastAPI, but an issue I'd appreciate any advice on.

I'm writing a small api server to receive webhook posts from a commercial provider.

They include the X-Signature header which they say is "generated by SHA256 hashing the JSON body and then building a SHA256 HMAC with the body hash as the data/content and your webhook secret as the key. "

As far as I understand, my attached code should do this, but when I run it, and it prints both their X-Sig header and the hash that I generate they never match.

I was hoping someone could offer some advice on whether I'm doing something obviously wrong.

For reference, this is some sample php code that they say will generate the required hash to match their own.

$json = file_get_contents('php://input'); $secret = "0d45982a10e3a072d0c1261c55dd9918"; $signature = hash_hmac('sha256', hash('sha256', $json), $secret);

Operating System

Linux, Windows

Operating System Details

No response

FastAPI Version

0.70.1

Python Version

3.9.9

Additional Context

No response

@baylf2000 baylf2000 added the question Question or problem label Dec 22, 2021
@insomnes
Copy link

I think your problem is here:

    message_body = await request.json()
    message_string = str(message_body)

You are calculating hmac from str repr of python object, which you get by json decoding, and not original request body.
You should use

await request.body()

Which will give you bytes of body, and calculate hmac based on it

Repository owner locked and limited conversation to collaborators Feb 28, 2023
@tiangolo tiangolo converted this issue into discussion #8713 Feb 28, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
question Question or problem question-migrate
Projects
None yet
Development

No branches or pull requests

3 participants