firebase-admin-python: Could not verify token signature.

[REQUIRED] Step 2: Describe your environment

  • Operating System version: Windows 10 1903
  • Library version: 4.2.0
  • Firebase Product: auth

[REQUIRED] Step 3: Describe the problem

I am developping a Flutter app inwhich I have a Facebook Sign In flow, then I authenticate the user on Firebase. In my backend code, I am using firebase_admin to authorize client calls, validating the tokens against firebase.

The mobile part is working fine and I was able to get the ID token once the firebase authentication flow succeeded. When I send the ID token to my backend to perform the token verification, it failes with the following stracktrace:

C:\ProgramData\Anaconda3\lib\site-packages\firebase_admin\auth.py in verify_id_token(id_token, app, check_revoked)
    192     """
    193     client = _get_client(app)
--> 194     return client.verify_id_token(id_token, check_revoked=check_revoked)
    195
    196

C:\ProgramData\Anaconda3\lib\site-packages\firebase_admin\_auth_client.py in verify_id_token(self, id_token, check_revoked)
    100                              ' bool, but given "{0}".'.format(type(check_revoked)))
    101
--> 102         verified_claims = self._token_verifier.verify_id_token(id_token)
    103         if self.tenant_id:
    104             token_tenant_id = verified_claims.get('firebase', {}).get('tenant')

C:\ProgramData\Anaconda3\lib\site-packages\firebase_admin\_token_gen.py in verify_id_token(self, id_token)
    236
    237     def verify_id_token(self, id_token):
--> 238         return self.id_token_verifier.verify(id_token, self.request)
    239
    240     def verify_session_cookie(self, cookie):

C:\ProgramData\Anaconda3\lib\site-packages\firebase_admin\_token_gen.py in verify(self, token, request)
    342             if 'Token expired' in str(error):
    343                 raise self._expired_token_error(str(error), cause=error)
--> 344             raise self._invalid_token_error(str(error), cause=error)
    345
    346     def _decode_unverified(self, token):

InvalidIdTokenError: Could not verify token signature.

Steps to reproduce:

I created a simple snippet that allows me to test the problem:

>>> import firebase_admin
>>> from firebase_admin import auth as firebase_auth
>>> credentials = firebase_admin.credentials.Certificate('service_account.json')
>>> firebase = firebase_admin.initialize_app(credentials)
>>> id_token = "..."  # Extracted from my client code after firebase authentication succeeded
>>> firebase_auth.verify_id_token(id_token)

Relevant Code:

Digging a bit deeper, I found out the the verification is failing in the pkcs1.py file:

def verify(message, signature, pub_key):
    ...
    method_name = _find_method_hash(clearsig)

The method _find_method_hash() above tries to look for byte sequence specific to hashing algos using the following definition:

HASH_ASN1 = {
    'MD5': b'\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10', 
    'SHA-1': b'\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14', 
    'SHA-224': b'\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c', 
    'SHA-256': b'\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20', 
    'SHA-384': b'\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30', 
    'SHA-512': b'\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40', 
}

and none of them matches the signature of the idToken I sent.

Let me know how can I help further.

Thanks!

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 17 (9 by maintainers)

Most upvoted comments

I had an epiphany just now.

When running Flutter from Android Studio, there is a hard limit on the number of characters that will be printed to stdout, with no indication that a truncation has occurred (as you can see the token doesn’t end on … or something to indicate that are characters omitted). When I get the full token it’s all working as expected.

I can’t believe how many hours of debugging I’ve spent on this… only to realize that there is no problem at all.

As a rule of thumb: don’t rely on flutter print statements.

I guess this issue is not meant to at all be part of this repository. Thanks for your help regardless guys!

Hey guys, we could get the complete token string by using log() method.

In my case, debugPrint(idToken) can only print 1014 characters of my token string. log(idToken) print 1146 characters which is a complete token string.

I must say that the problem is indeed unusual, but I think its no coincidence that I get an error at the exact same line as @hrqnogueira in the pkcs1.py.

I tried verifying the token with the Java Firebase admin SDK where it gave the same error ‘Could not verify signature’. Does that mean that I’ve somehow failed to properly setup Firebase on both the client and server apps? Let me walk through a detailed description of the project setup:

Firstly on the mobile app, users log in with google sign-in:

final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(
  accessToken: googleAuth.accessToken,
  idToken: googleAuth.idToken,
);
await _firebaseAuth.signInWithCredential(credential);

Then I get Firebase ID tokens like this:

FirebaseUser user = await _firebaseAuth.currentUser();
IdTokenResult token = await user.getIdToken();
print(token.token);

The mobile app is linked to Firebase following Google’s instructions from here https://firebase.google.com/docs/flutter/setup I think that users appearing on the Firebase console as I log them in from the app is a confirmation that the setup is done properly? image

Then, for the backend, I have downloaded a service account private key .json file and i use it to initialize the app:

import firebase_admin
from firebase_admin import credentials
import os

cred = credentials.Certificate(os.path.join(os.path.dirname(os.path.abspath(__file__)), "firebase_credentials.json"))
firebase_admin.initialize_app(cred)

Then i try to verify the ID token which i get from Flutter like so:

from firebase_admin import auth

token = "... token from Flutter print() here"
decoded_token = auth.verify_id_token(token)

At this point I get an error: image

To dig deeper into the error I will put 2 breakpoints:

  • google.auth.jwt line 235
  • rsa.pkcs1.py line 417

Note, how at the first breakpoint, the token’s payload is indeed successfully decoded: image

At the second breakpoint it tries to match the clearsig with MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 and after nothing matches, it throws an error which cascades back to the auth.verify_id_token(token) method call image

You guys just saved from a heart attack. I spent my whole day trying to figure out the cause and truncation was the issue. Thanks guys.

As I said, it is always due to truncation. Glad you figured it out.

Same here, I checked the token and it has an invalid signature. If this is a one off and there is no reliable way to replicate it, then I would close this.

Most of the issues we’ve seen before have been due to some truncation.

Im obtaining it from the flutter client app like so:

FirebaseUser user = await _firebaseAuth.currentUser();
IdTokenResult token = await user.getIdToken();
print(token.token);

I made sure its not truncated. The fireabase user is the result of signing in with Google Sign In.

I am experiencing the exact same problem, except my flutter app authenticates users with Google sign in rather than Facebook. Any suggestions?