mpdavis / python-jose

A JOSE implementation in Python
MIT License
1.55k stars 237 forks source link

Docs need to be clearer regarding verification of signature #153

Open ruddymondal opened 5 years ago

ruddymondal commented 5 years ago

I wanted to verify a signature I had previously generated with ES256.

Creating the signature was straightforward. Since JOSE was using cryptography as the backend, I used the private_bytes method to serialize the private key and then added the parameter to JOSE's JWS sign method. Worked perfectly.

Wanting to test the verification of said signature, I did the same to serialize the public key using the public_bytes method. However, I got this peculiar error thrown at me:

  File "/home/ruddymondal/.local/lib/python3.6/site-packages/jose/jws.py", line 77, in verify
    _verify_signature(signing_input, header, signature, key, algorithms)
  File "/home/ruddymondal/.local/lib/python3.6/site-packages/jose/jws.py", line 262, in _verify_signature
    keys = _get_keys(key)
  File "/home/ruddymondal/.local/lib/python3.6/site-packages/jose/jws.py", line 229, in _get_keys
    if 'keys' in key:
TypeError: a bytes-like object is required, not 'str'

Peculiar because the public key is already serialized.

So I go the last function _get_keys in the trace and realize I need to send a dictionary object instead with the public key assigned to the key keys. Or so I thought.

So I try again and get this error:

  File "/home/ruddymondal/.local/lib/python3.6/site-packages/jose/jws.py", line 77, in verify
    _verify_signature(signing_input, header, signature, key, algorithms)
  File "/home/ruddymondal/.local/lib/python3.6/site-packages/jose/jws.py", line 264, in _verify_signature
    if not _sig_matches_keys(keys, signing_input, signature, alg):
  File "/home/ruddymondal/.local/lib/python3.6/site-packages/jose/jws.py", line 212, in _sig_matches_keys
    key = jwk.construct(key, alg)
  File "/home/ruddymondal/.local/lib/python3.6/site-packages/jose/jwk.py", line 61, in construct
    return key_class(key_data, algorithm)
  File "/home/ruddymondal/.local/lib/python3.6/site-packages/jose/backends/cryptography_backend.py", line 66, in __init__
    raise JWKError('Unable to parse an ECKey from key: %s' % key)
jose.exceptions.JWKError: Unable to parse an ECKey from key: 45

Peculiar. So I go into the source code again and realize that in the function _sig_matches_keys the key is being called with for key in keys. Okay so I put the key in a list and assign it to the key "keys" in the dictionary.

Now it works.

The question is, why wasn't all of this elucidated in the docs? I understand that it's probably detailed in the RFC but wouldn't it be preferable in the interest of ease of development for the above to be mentioned in the docs as well?

I would love to create a pull request if you're okay with that. Thanks.

blag commented 4 years ago

I would love to create a pull request if you're okay with that. Thanks.

Yes please!