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!
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))