google-auth-library-python: Getting "Invalid JWT Signature" after upgrading to rsa==4.7

Environment details

  • OS: Linux, Mac
  • Python version: 3.7, 3.8
  • pip version: 20.3.3
  • google-auth version: 1.22.1

Steps to reproduce

We found this bug while using dvc and using Google Cloud Storage as a backend. Authentication with google is done via a service key file. When running dvc with rsa==4.6 everything works fine, but when upgrading to rsa==4.7, we encounter the following error:

  File "/home/alvaro/.virtualenvs/myenv/lib/python3.7/site-packages/dvc/tree/gs.py", line 139, in isfile
    return blob.exists()
  File "/home/alvaro/.virtualenvs/myenv/lib/python3.7/site-packages/google/cloud/storage/blob.py", line 484, in exists
    _target_object=None,
  File "/home/alvaro/.virtualenvs/myenv/lib/python3.7/site-packages/google/cloud/_http.py", line 431, in api_request
    timeout=timeout,
  File "/home/alvaro/.virtualenvs/myenv/lib/python3.7/site-packages/google/cloud/_http.py", line 289, in _make_request
    method, url, headers, data, target_object, timeout=timeout
  File "/home/alvaro/.virtualenvs/myenv/lib/python3.7/site-packages/google/cloud/_http.py", line 327, in _do_request
    url=url, method=method, headers=headers, data=data, timeout=timeout
  File "/home/alvaro/.virtualenvs/myenv/lib/python3.7/site-packages/google/auth/transport/requests.py", line 460, in request
    self.credentials.before_request(auth_request, method, url, request_headers)
  File "/home/alvaro/.virtualenvs/myenv/lib/python3.7/site-packages/google/auth/credentials.py", line 133, in before_request
    self.refresh(request)
  File "/home/alvaro/.virtualenvs/myenv/lib/python3.7/site-packages/google/oauth2/service_account.py", line 361, in refresh
    access_token, expiry, _ = _client.jwt_grant(request, self._token_uri, assertion)
  File "/home/alvaro/.virtualenvs/myenv/lib/python3.7/site-packages/google/oauth2/_client.py", line 153, in jwt_grant
    response_data = _token_endpoint_request(request, token_uri, body)
  File "/home/alvaro/.virtualenvs/myenv/lib/python3.7/site-packages/google/oauth2/_client.py", line 124, in _token_endpoint_request
    _handle_error_response(response_body)
  File "/home/alvaro/.virtualenvs/myenv/lib/python3.7/site-packages/google/oauth2/_client.py", line 60, in _handle_error_response
    raise exceptions.RefreshError(error_details, response_body)
google.auth.exceptions.RefreshError: ('invalid_grant: Invalid JWT Signature.', '{"error":"invalid_grant","error_description":"Invalid JWT Signature."}')

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 3
  • Comments: 18 (9 by maintainers)

Commits related to this issue

Most upvoted comments

Thanks for collaborating on this, people! 🥳 🎈

Hi @busunkim96 , after installing cryptography and removing rsa, I get a new error when running the same code in our work project:

waluigi/tests/contrib/gcs/wa_gcs_client/test_remove.py:26: in full_dir_path
    wa_client.put_multiple(filepaths, dir_path, num_process=20)
venv/lib/python3.6/site-packages/luigi/contrib/gcs.py:280: in put_multiple
    return p.map(self._forward_args_to_put, put_kwargs_list)
/usr/local/lib/python3.6/multiprocessing/pool.py:266: in map
    return self._map_async(func, iterable, mapstar, chunksize).get()
/usr/local/lib/python3.6/multiprocessing/pool.py:644: in get
    raise self._value
/usr/local/lib/python3.6/multiprocessing/pool.py:424: in _handle_tasks
    put(task)
/usr/local/lib/python3.6/multiprocessing/connection.py:206: in send
    self._send_bytes(_ForkingPickler.dumps(obj))
/usr/local/lib/python3.6/multiprocessing/reduction.py:51: in dumps
    cls(buf, protocol).dump(obj)
E   TypeError: can't pickle _cffi_backend.FFI objects

Some context - waluigi is our vendored wrapper around Luigi. We’re using luigi.contrib.gcs’s put_multiple() to upload multiple files in parallel to GCS.

It looks like the _cffi_backend.FFI objects are from https://github.com/cffi/cffi which is required by cryptography:

$ pip install cryptography
Requirement already satisfied: cryptography in ./venv/lib/python3.6/site-packages (3.4.6)
Requirement already satisfied: cffi>=1.12 in ./venv/lib/python3.6/site-packages (from cryptography) (1.14.4)
Requirement already satisfied: pycparser in ./venv/lib/python3.6/site-packages (from cffi>=1.12->cryptography) (2.20)

Hope that’s helpful.

I’m the author of the RSA package. As you can see in sybrenstuvel/python-rsa#173, there is a problem where attributes on the key objects are missing:

  File "/usr/local/lib/python3.6/multiprocessing/pool.py", line 119, in worker
    result = (True, func(*args, **kwds))
  File "/usr/local/lib/python3.6/multiprocessing/pool.py", line 44, in mapstar
    return list(map(*args))
  File "/usr/local/lib/python3.6/site-packages/luigi/contrib/gcs.py", line 258, in _forward_args_to_put
    return self.put(**kwargs)
  File "/usr/local/lib/python3.6/site-packages/luigi/contrib/gcs.py", line 255, in put
    self._do_put(media, dest_path)
  File "/usr/local/lib/python3.6/site-packages/luigi/contrib/gcs.py", line 173, in _do_put
    status, response = request.next_chunk()
  File "/usr/local/lib/python3.6/site-packages/googleapiclient/_helpers.py", line 134, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/googleapiclient/http.py", line 993, in next_chunk
    headers=start_headers,
  File "/usr/local/lib/python3.6/site-packages/googleapiclient/http.py", line 177, in _retry_request
    resp, content = http.request(uri, method, *args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/google_auth_httplib2.py", line 190, in request
    self._request, method, uri, request_headers)
  File "/usr/local/lib/python3.6/site-packages/google/auth/credentials.py", line 133, in before_request
    self.refresh(request)
  File "/usr/local/lib/python3.6/site-packages/google/oauth2/service_account.py", line 360, in refresh
    assertion = self._make_authorization_grant_assertion()
  File "/usr/local/lib/python3.6/site-packages/google/oauth2/service_account.py", line 354, in _make_authorization_grant_assertion
    token = jwt.encode(self._signer, payload)
  File "/usr/local/lib/python3.6/site-packages/google/auth/jwt.py", line 112, in encode
    signature = signer.sign(signing_input)
  File "/usr/local/lib/python3.6/site-packages/google/auth/crypt/_python_rsa.py", line 136, in sign
    return rsa.pkcs1.sign(message, self._key, "SHA-256")
  File "/usr/local/lib/python3.6/site-packages/rsa/pkcs1.py", line 331, in sign
    return sign_hash(msg_hash, priv_key, hash_method)
  File "/usr/local/lib/python3.6/site-packages/rsa/pkcs1.py", line 306, in sign_hash
    encrypted = priv_key.blinded_encrypt(payload)
  File "/usr/local/lib/python3.6/site-packages/rsa/key.py", line 463, in blinded_encrypt
    blinded = self.blind(message)  # blind before encrypting
  File "/usr/local/lib/python3.6/site-packages/rsa/key.py", line 165, in blind
    self._update_blinding_factor()
  File "/usr/local/lib/python3.6/site-packages/rsa/key.py", line 190, in _update_blinding_factor
    if self.blindfac < 0:
AttributeError: blindfac

Is Google Auth creating the keys in some non-standard way? The self.blindfac attribute is set in the key’s __init__() function, so I don’t see how it could be missing.

Hi,

Thanks for the report! I’ve marked this as external for now since I see you also opened https://github.com/sybrenstuvel/python-rsa/issues/173. Please let me know if something needs to be fixed in this library.