Problem signing JWT with ES or RS algorithm
Hi !
I am trying to use the ES256 algorithm to sign all my token but for some reason I receive errors when I try to do that. I use Python 3.7 with python-jose 3.3.0. I tried with version 3.2.0 and python 3.8 but it doesn't change anything. Here is the code I use for sample.
I do not have the problem if I use the HS algorithm.
from jose import jwt
token = jwt.encode({'iss': 'me'}, 'secret', algorithm='ES256')
print(token)
I get the 4 following errors as a result:
/Users/troplolBE/PycharmProjects/api/venv/lib/python3.8/site-packages/jose/backends/cryptography_backend.py:18: CryptographyDeprecationWarning: int_from_bytes is deprecated, use int.from_bytes instead
from cryptography.utils import int_from_bytes, int_to_bytes
Traceback (most recent call last):
File "/Users/troplolBE/PycharmProjects/api/venv/lib/python3.8/site-packages/jose/backends/cryptography_backend.py", line 61, in __init__
key = load_pem_public_key(key, self.cryptography_backend())
File "/Users/troplolBE/PycharmProjects/api/venv/lib/python3.8/site-packages/cryptography/hazmat/primitives/serialization/base.py", line 30, in load_pem_public_key
return ossl.load_pem_public_key(data)
File "/Users/troplolBE/PycharmProjects/api/venv/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 853, in load_pem_public_key
self._handle_key_loading_error()
File "/Users/troplolBE/PycharmProjects/api/venv/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1129, in _handle_key_loading_error
raise ValueError(
ValueError: ('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [_OpenSSLErrorWithText(code=151584876, lib=9, reason=108, reason_text=b'error:0909006C:PEM routines:get_name:no start line')])
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/troplolBE/PycharmProjects/api/venv/lib/python3.8/site-packages/jose/backends/cryptography_backend.py", line 63, in __init__
key = load_pem_private_key(key, password=None, backend=self.cryptography_backend())
File "/Users/troplolBE/PycharmProjects/api/venv/lib/python3.8/site-packages/cryptography/hazmat/primitives/serialization/base.py", line 22, in load_pem_private_key
return ossl.load_pem_private_key(data, password)
File "/Users/troplolBE/PycharmProjects/api/venv/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 823, in load_pem_private_key
return self._load_key(
File "/Users/troplolBE/PycharmProjects/api/venv/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1070, in _load_key
self._handle_key_loading_error()
File "/Users/troplolBE/PycharmProjects/api/venv/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1129, in _handle_key_loading_error
raise ValueError(
ValueError: ('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [_OpenSSLErrorWithText(code=151584876, lib=9, reason=108, reason_text=b'error:0909006C:PEM routines:get_name:no start line')])
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/troplolBE/PycharmProjects/api/venv/lib/python3.8/site-packages/jose/jws.py", line 169, in _sign_header_and_claims
key = jwk.construct(key_data, algorithm)
File "/Users/troplolBE/PycharmProjects/api/venv/lib/python3.8/site-packages/jose/jwk.py", line 60, in construct
return key_class(key_data, algorithm)
File "/Users/troplolBE/PycharmProjects/api/venv/lib/python3.8/site-packages/jose/backends/cryptography_backend.py", line 65, in __init__
raise JWKError(e)
jose.exceptions.JWKError: ('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [_OpenSSLErrorWithText(code=151584876, lib=9, reason=108, reason_text=b'error:0909006C:PEM routines:get_name:no start line')])
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "research.py", line 4, in <module>
token = jwt.encode({'iss': 'me'}, 'secret', algorithm='ES256')
File "/Users/troplolBE/PycharmProjects/api/venv/lib/python3.8/site-packages/jose/jwt.py", line 64, in encode
return jws.sign(claims, key, headers=headers, algorithm=algorithm)
File "/Users/troplolBE/PycharmProjects/api/venv/lib/python3.8/site-packages/jose/jws.py", line 50, in sign
signed_output = _sign_header_and_claims(encoded_header, encoded_payload, algorithm, key)
File "/Users/troplolBE/PycharmProjects/api/venv/lib/python3.8/site-packages/jose/jws.py", line 172, in _sign_header_and_claims
raise JWSError(e)
jose.exceptions.JWSError: ('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [_OpenSSLErrorWithText(code=151584876, lib=9, reason=108, reason_text=b'error:0909006C:PEM routines:get_name:no start line')])
HS* is an HMAC algorithm, so passing a simple string as the secret key works. RS* (RSA) and ES* (ECDSA) algorithms use asymmetric cryptography, so the secret has to be a proper private key. See https://auth0.com/blog/json-web-token-signing-algorithms-overview/ for a brief overview.
If you want to experiment with different algorithms and keys, this key generator website is quite handy: https://mkjwk.org/
If you pass "Private Key (X.509 PEM Format)" from that website as the secret, it should work. For example:
private_key = """
-----BEGIN PRIVATE KEY-----
MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCAhjKwOYyR1c8/xHS9S
OhK+LAcg27Txp/KaR+6lDRu4jg==
-----END PRIVATE KEY-----
"""
token = jwt.encode({'iss': 'me'}, private_key, algorithm='ES256')