Перейти к содержимому
ecdsa.com
PyJWT (Python)Библиотеки JWT

Сообщение об ошибке

Signature verification failed

PyJWT (Python) — jwt.exceptions.InvalidSignatureError

Что это означает

PyJWT разобрал структуру токена и выполнил проверку подписи, но она не прошла: подпись не соответствует ключу и полезной нагрузке. InvalidSignatureError — подкласс DecodeError, поэтому слишком широкий except DecodeError может выдать эту ошибку за проблему разбора, хотя на самом деле ключ не соответствует содержимому. Для токенов ES256 есть ещё одна тонкость: подпись JWS должна быть в формате raw r‖s длиной 64 байта, поэтому токены, выпущенные самописным кодом подписи, который выдавал ASN.1 DER, не проходят здесь проверку, даже если ключ правильный.

Почему это происходит

Как исправить

  1. 1.

    Вычислите отпечаток ключа на обеих сторонах

    Выведите отпечаток SHA-256 открытого ключа, который загрузила проверяющая сторона, и сравните его с отпечатком ключа издателя. Если они различаются, причина найдена; если совпадают, проблему нужно искать в байтах токена.

    python
    import hashlib
    from cryptography.hazmat.primitives import serialization
    
    public_key = serialization.load_pem_public_key(pem_bytes)  # the key the verifier uses
    spki = public_key.public_bytes(serialization.Encoding.DER, serialization.PublicFormat.SubjectPublicKeyInfo)
    print(hashlib.sha256(spki).hexdigest())  # compare with the issuer's
  2. 2.

    Проверьте kid, прежде чем подозревать повреждение

    Прочитайте заголовок без проверки и убедитесь, что проверяете ключом, который указан в токене. Если у издателя несколько ключей, выбирайте нужный по kid через PyJWKClient.

    python
    import jwt
    
    header = jwt.get_unverified_header(token)
    print(header)  # {'alg': 'ES256', 'kid': '...'}
    
    from jwt import PyJWKClient
    key = PyJWKClient("https://issuer.example/.well-known/jwks.json") \
        .get_signing_key_from_jwt(token).key
    payload = jwt.decode(token, key, algorithms=["ES256"], audience="api://orders")

Связанные ошибки

Открыть всю базу ошибок подписей