androidsafetynet

JWS from Google SafetyNet contains different nonce value than one I submitted in attest()


I'm trying to implement SafetyNet in an Android app but am running into this issue:

The JWS that I receive show the nonce as a particular value, but it is different than the one I passed in here:

 Task<SafetyNetApi.AttestationResponse> task = client.attest(nonce.getBytes(), apiKey);
    task.addOnSuccessListener(this, new OnSuccessListener<SafetyNetApi.AttestationResponse>() {
        @Override
        public void onSuccess(SafetyNetApi.AttestationResponse attestationResponse) {             
            handleJWS(attestationResponse.getJwsResult());

        }
    }).addOnFailureListener(this, new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            if (BuildConfig.DEBUG)
                Log.d("cts", "fail " + e.toString());
        }
    });

I use nonce.getBytes() as a parameter, as the nonce generated from the server is a String.

I've read the documentation over and over again, but can't figure out why the nonce value I receive as part of the JWS doesn't match the value I put in the attest() method. If this is expected, why is this so and how can I get the server to expect this value in order to verify it?

Any ideas?

Thanks!


Solution

  • I had the same issue and just figured out what was wrong: the nonce, apkDigestSha256 and the values of apkCertificateDigestSha256 are Base64 encoded! See https://github.com/googlesamples/android-play-safetynet/blob/master/server/java/src/main/java/AttestationStatement.java

    In order to compare your nonce with the one from the JWS you have to do:

    Arrays.equals(yourNonce, Base64.decode(attestationStatement.nonce(), Base64.DEFAULT))