Сообщение об ошибке
The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.
Также выводится как
- jwt.exceptions.InvalidKeyError: The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.
PyJWT (Python) — jwt.exceptions.InvalidKeyError from HMACAlgorithm.prepare_key
Что это означает
Вызывающий код передал PyJWT открытый ключ, закрытый ключ или сертификат в формате PEM как секрет для алгоритма HMAC (HS256/384/512), и PyJWT отказался его использовать. Эта защита существует из-за известного класса ошибок в реализациях JWT: если проверяющая сторона принимает и алгоритмы RS/ES, и алгоритмы HS с одним и тем же аргументом key, любой, кто знает открытый ключ, может вычислить верный HMAC для поддельного токена. Здесь в заголовке токена указан алгоритм HMAC, который есть в вашем списке разрешённых алгоритмов.
Почему это происходит
В списке разрешённых алгоритмов смешаны HMAC и асимметричные алгоритмы
часто`algorithms=["RS256", "HS256"]` вместе с открытым ключом означает, что токен HS256 пытается использовать этот открытый ключ как секрет HMAC. Если это разрешить, поддельный токен пройдёт проверку; PyJWT этого не допускает.
В настройках сервиса задан HS256, а ключ хранится в формате PEM
иногдаВ конфигурации указано `JWT_ALGORITHM=HS256`, а в `JWT_KEY` лежит PEM-файл. Выясните, какую схему на самом деле использует издатель, и приведите оба значения в соответствие.
Кто-то прощупывает проверяющую сторону
иногдаТокены с `alg: "HS256"`, которые приходят в API, чей издатель подписывает RSA или ECDSA, — классическая проба на уязвимость к подмене алгоритма. Зафиксируйте в журнале источник; эта ошибка означает, что проба не удалась.
Как исправить
- 1.
Разрешите для каждого ключа только одно семейство алгоритмов
Передавайте вместе с открытым ключом издателя только те асимметричные алгоритмы, которые он использует, а проверку HMAC (если она вообще нужна) вынесите в отдельную ветку кода с собственным случайным секретом.
python # Asymmetric issuer: allow only asymmetric algorithms with the public key. claims = jwt.decode(token, public_key, algorithms=["ES256"], audience="https://api.example.com") # Shared-secret tokens: a random secret, never a PEM, and only HMAC algorithms. claims = jwt.decode(token, HMAC_SECRET, algorithms=["HS256"], audience="internal")