jws.sign is not working with algorithm RS256

1.3k views Asked by At

I am trying to sign a JSON encoded object with jws.sign and hence tried this example given here: https://python-jose.readthedocs.io/en/latest/jws/index.html

But problem is that jws.sign is working fine with algorithm HS256 given in the example above but fails with algorithm RS256 with this error:

signed = jws.sign({'a': 'b'}, 'secret', algorithm='RS256') Traceback (most recent call last): File "/usr/local/lib/python3.7/dist-packages/jose/backends/cryptography_backend.py", line 231, in init self.prepared_key = load_pem_public_key(key, self.cryptography_backend()) File "/usr/local/lib/python3.7/dist-packages/cryptography/hazmat/primitives/serialization/base.py", line 23, in load_pem_public_key return backend.load_pem_public_key(data) File "/usr/local/lib/python3.7/dist-packages/cryptography/hazmat/backends/openssl/backend.py", line 1273, in load_pem_public_key self._handle_key_loading_error() File "/usr/local/lib/python3.7/dist-packages/cryptography/hazmat/backends/openssl/backend.py", line 1526, in _handle_key_loading_error raise ValueError("Could not deserialize key data.") ValueError: Could not deserialize key data.

Any leads will be helpful

1

There are 1 answers

0
HaggarTheHorrible On

I was in the same situation as you were, for several days, after a lot of searching I finally understood what the problem was and I came up with the solution below. Let me explain.

  1. Example that WILL NOT work
from jose import jws
signed = jws.sign({'a': 'b'}, 'secret', algorithm='RS256')

Output:

jose.exceptions.JWSError: Could not deserialize key data.

  1. Issues

    The 'secret' used as a key is applicable for HS256 algorithm, however, it is not applicable for RS256 algorithm.

  2. Improvements needed

    • Go to a RSA Key Generator website such as: https://cryptotools.net/rsagen and generate a key. (Retain default settings on the website.)

    • Copy the Private and Public Keys into separate variables in your code. We need the Public Key to verify.

    • Note: Retain the newlines AFTER -----BEGIN RSA PRIVATE KEY----- and BEFORE -----END RSA PRIVATE KEY-----. They are a must, if you miss them then you will again get the deserialize error.

Generating a new RSA Private Key.

  1. Working Example
from jose import jws

private_key = '''
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCUn8GgYNd49UCmHZl0cmbHQucMJEPZQoCzisBZ3D80jlhea6di
dPrPHNhb9JNNOY2W4Ip6AfggbpFeemUhPhD88yz8Y9ntNzH0ztEC6JV5lSyhOKLn
f+pccfXvHwakXXIRpHKoCqIUPDKtiyo6S9zjfihkHkh+jDY7dgvaQJAvkQIDAQAB
AoGAdUiAntPtFbnME4qGH1tr+dC0zWMM27TcJVLYKdFhW1L9Lz2a8FpJ1gj4P9CI
MUe6kRaOkGtfaBB4zOqfRZVaB13OMSn3JnXeP4VpzFpFYKJCeKfrnbiIFMqzarfg
Kk8FSVHxSs3pZQtLhmUxx1CfjOUgIj0UKhfnhyLmh4zc80ECQQDUglcCfssFioVe
PSWOoi6LXwGxky2StoiUg/AH6RDtDZDhJi5pHgwtPWJkqvKTmoJvgp8A7Qvn8eCl
5A2xuN3JAkEAswpiamr8gme09Z9f5dbTd62fKMq+n5eVa/C9Uqt1FGTCOcjELp6z
z4km7rgz7DNS1R0E3q2Y8c5SRvPbNokHiQJAaKeD2Cu/Kgxs39s3KsY+K87vE5eK
wwz3uEQ9qneiKUwcBHV8N7JfhswLL85sRjq6b9YhHiCfU2vwGWJ1SAfl2QJAA40t
Lpc4sw2DlWu350M/ppwXECQVa+0B1cZMuxsTk3f8MlE9Mv+K6Y766rlUrlbGSdvt
gM1Iv2MsVqP3sTk+oQJABkHcGx+31fcKJoWgx+yjMuN2eo13hQD/Ie4hUXnM6nF2
vzqiaNCgAA4udqFRVGjqa5Lb8rdbALFzja2fuSH4eQ==
-----END RSA PRIVATE KEY-----
'''
signed = jws.sign({'name': 'Jai Seeta Ram'}, private_key, algorithm='RS256')

print("Output 1:", signed)

public_key = '''
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUn8GgYNd49UCmHZl0cmbHQucM
JEPZQoCzisBZ3D80jlhea6didPrPHNhb9JNNOY2W4Ip6AfggbpFeemUhPhD88yz8
Y9ntNzH0ztEC6JV5lSyhOKLnf+pccfXvHwakXXIRpHKoCqIUPDKtiyo6S9zjfihk
Hkh+jDY7dgvaQJAvkQIDAQAB
-----END PUBLIC KEY-----
'''
print("Output 2: ", jws.verify(signed, public_key, algorithms='RS256'))

Output:

Output 1: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSmFpIFNlZXRhIFJhbSJ9.aEEq-ZBA88DL96XO5rLunRUIhd3zCtb1r0ItPnP1d2yKFJ4agkykzYvHVvHa1muKUPwi9HEbxvKf4GXHtl2VF_xOJPJUsRfTGYbMwsrZ1KomdDmdEtiqEa-59spXAGMUCpFXNED7pChnHeNGEaxiOXqa_N7zqIf1NEV75ku_83w
Output 2:  b'{"name":"Jai Seeta Ram"}'