Получение неверной подписи HMA C SHA256 по сравнению с примером JWT - PullRequest
2 голосов
/ 23 марта 2020

Я пытаюсь выполнить RF C для JSON веб-подписей (A.1.1), но у меня возникают проблемы при следовании примеру.

Я получаю все до конца, где я не могу сгенерировать такую ​​же подпись. Вот пример Python 3.8 код:

import hmac
import hashlib
import base64
signing_input = b"eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ"
key = b"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"
signature = hmac.digest(key, signing_input, digest=hashlib.sha256)

print(base64.urlsafe_b64encode(signature))
# Output: b'ZekyXWlxvuCN9H8cuDrZfaRa3pMJhHpv6QKFdUqXbLc='
# Expected: b'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk'

Кроме того, я попробовал несколько онлайн-инструментов, которые обрабатывают HMA C -SHA256, но я получаю тот же вывод, что и мой скрипт Python. Любые идеи о том, где я иду не так?

1 Ответ

3 голосов
/ 23 марта 2020

Вы используете не тот ключ. RF C показывает ключ в формате JSON веб-ключ с использованием JSON веб-алгоритма "oct". Это означает, что ключ является закодированной в base64url последовательностью байтов. Вам нужно декодировать его перед использованием, если вы хотите, чтобы ваши результаты соответствовали.

Обратите внимание, что python urlsafe_b64decode и urlsafe_b64encode не совсем реализуют кодировку base64url, используемую JWT и друзьями. python функции ожидают / производят символы заполнения, которые должна быть удалена кодировкой base64url, используемой JWT.

Собираем все это вместе:

import hmac
import hashlib
import base64

signing_input = b"eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ"
key = b"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"

# Decode the key.  Pad it with '=' characters to a length divisible by 4 
# as expected by urlsafe_b64decode
if len(key) % 4 == 2:
    key += b'=='
elif len(key) % 4 == 3:
    key += b'='

key = base64.urlsafe_b64decode(key)

signature = hmac.digest(key, signing_input, digest=hashlib.sha256)
signature = base64.urlsafe_b64encode(signature)

# Strip off any '=' characters urlsafe_b64encode added to pad the key to
# a length divisible by 4
signature = signature.rstrip(b'=')
print(signature)
# Prints: b'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk'
...