Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions docs/en/latest/plugins/hmac-auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -887,6 +887,10 @@ body = '{"name": "world"}' # example request body
# skew to prolong the validity within the advised security boundary
gmt_time = datetime.now(timezone.utc).strftime('%a, %d %b %Y %H:%M:%S GMT')

# create the SHA-256 digest of the request body and base64 encode it
body_digest = hashlib.sha256(body.encode('utf-8')).digest()
body_digest_base64 = base64.b64encode(body_digest).decode('utf-8')

# construct the signing string (ordered)
# the date and any subsequent custom headers should be lowercased and separated by a
# single space character, i.e. `<key>:<space><value>`
Expand All @@ -895,23 +899,20 @@ signing_string = (
f"{key_id}\n"
f"{request_method} {request_path}\n"
f"date: {gmt_time}\n"
f"digest: SHA-256={body_digest_base64}\n"
)

# create signature
signature = hmac.new(secret_key, signing_string.encode('utf-8'), hashlib.sha256).digest()
signature_base64 = base64.b64encode(signature).decode('utf-8')

# create the SHA-256 digest of the request body and base64 encode it
body_digest = hashlib.sha256(body.encode('utf-8')).digest()
body_digest_base64 = base64.b64encode(body_digest).decode('utf-8')

# construct the request headers
headers = {
"Date": gmt_time,
"Digest": f"SHA-256={body_digest_base64}",
"Authorization": (
f'Signature keyId="{key_id}",algorithm="hmac-sha256",'
f'headers="@request-target date",'
f'Signature keyId="{key_id}",algorithm="{algorithm}",'
f'headers="@request-target date digest",'
f'signature="{signature_base64}"'
)
}
Expand Down Expand Up @@ -972,6 +973,10 @@ You should see an `HTTP/1.1 200 OK` response similar to the following:
}
```

:::note
`validate_request_body` only checks that the `Digest` header matches the request body. To bind the body integrity to the HMAC signature and ensure end-to-end protection, you must also include the `Digest` header in the signed headers list (as shown above) or enforce it via the route-level `signed_headers` configuration option.
:::

If you send a request without the digest or with an invalid digest:

```shell
Expand Down
Loading