Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Cloud Endpoints: verifyToken: Signature length not correct

Tags:

This morning the following exception has started occuring on every API request to my Google Cloud Endpoint from my Android app:

com.google.api.server.spi.auth.GoogleIdTokenUtils verifyToken: verifyToken: Signature length not correct: got 256 but was expecting 128

The call still works perfectly from my javascript web clients. I have changed nothing on the server side code or client code.

Has anything changed with the service recently that might make this occur?

UPDATE: The first occurrence of this appears to have been at 11:17:07 UTC

UPDATE: Things that don't work include generating a new Client ID for android & updating to App Engine SDK 1.9.22

like image 947
Tom Avatar asked Jun 11 '15 13:06

Tom


1 Answers

The causes

  • RSA has variable length signatures, depending on the key size.
  • Google updated the key pairs it uses for signing, and now one of the key pairs generates a different length signature from the other
  • java.security.Signature.verify(byte[] signature) throws an exception if a signature of the wrong length is passed (instead of returning false which is normally done when a signature does not match the key)

For me the solution was to wrap the verify call (try...catch), and return false instead. You could also do an early check on the public key yourself, checking if the length of the signature matches the length of the public key modulus.

If you use a library to check the signature, make sure you use the latest version.

Looking at the example code on http://android-developers.blogspot.nl/2013/01/verifying-back-end-calls-from-android.html, you would have to change this:

GoogleIdToken token = GoogleIdToken.parse(mJFactory, tokenString); 

to

JsonWebSignature jws = JsonWebSignature.parser(mJFactory).setPayloadClass(Payload.class).parse(tokenString); GoogleIdToken token = new GoogleIdToken(jws.getHeader(), (Payload) jws.getPayload(), jws.getSignatureBytes(), jws.getSignedContentBytes()) {    public boolean verify(GoogleIdTokenVerifier verifier)   throws GeneralSecurityException, IOException {        try {            return verifier.verify(this);        } catch (java.security.SignatureException e) {            return false;        }    } }; 

I unfortunately don't have an exact setup to test this.

For those using Google Cloud Endpoint, like the question states, I think there was very little you could do except wait until Google fixes it. Luckily it's fixed now. (Technically, you could argue changing the keys, as is done now, is a workaround, and the library Google provides needs to be fixed. But it works, so that's a good start)

like image 55
beetstra Avatar answered Oct 17 '22 17:10

beetstra