Skip to content

Instantly share code, notes, and snippets.

@ganadist
Last active March 3, 2021 20:24
Show Gist options
  • Save ganadist/2af47d422ca6f9d30e8d to your computer and use it in GitHub Desktop.
Save ganadist/2af47d422ca6f9d30e8d to your computer and use it in GitHub Desktop.
SafetyNet example
private static final DEBUG = false;
private static final SecureRandom SR;
static {
SR = new SecureRandom();
SR.setSeed(System.currentTimeMillis());
}
private byte[] getRequestNonce() {
byte[] output = new byte[16];
SR.nextBytes(output);
return output;
}
private static final com.google.api.client.json.JsonFactory JSON_FACTORY =
com.google.api.client.extensions.android.json.AndroidJsonFactory.getDefaultInstance();
private static final com.google.api.client.json.webtoken.JsonWebSignature.Parser JWS_PARSER =
new com.google.api.client.json.webtoken.JsonWebSignature.Parser(JSON_FACTORY);
private boolean validatePayload(JsonWebToken.Payload payload, byte[] nonce) {
if (DEBUG) {
try {
Log.d(TAG, "payload = " + payload.toPrettyString());
} catch (IOException ex) { }
}
if (payload.containsKey("error")) {
Log.e(TAG, "payload has error field: " + payload.get("error"));
return false;
}
if (!(boolean)(payload.get("ctsProfileMatch"))) {
Log.e(TAG, "cts profile is not matched");
return false;
}
if (! getPackageName().equals(payload.get("apkPackageName"))) {
Log.e(TAG, "invalid package name: " + payload.get("apkPackageName"));
return false;
}
final String payloadNonce = (String)payload.get("nonce");
final String requested = Base64.encodeToString(nonce, Base64.NO_WRAP);
if (!requested.equals(payloadNonce)) {
Log.e(TAG, "invalid nonce");
Log.e(TAG, "requested = \"" + requested + "\"");
Log.e(TAG, "payload = \"" + payloadNonce + "\"");
return false;
}
Log.v(TAG, "jws token is valid");
return true;
}
/**
* Called when {@code mGoogleApiClient} is connected.
*/
@Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "GoogleApiClient connected");
// TODO: Start making API requests.
final byte[] nonce = getRequestNonce();
SafetyNet.SafetyNetApi.attest(mGoogleApiClient, nonce)
.setResultCallback(new ResultCallback<SafetyNetApi.AttestationResult>() {
@Override
public void onResult(SafetyNetApi.AttestationResult result) {
Status status = result.getStatus();
String jws = result.getJwsResult();
if (status.isSuccess() && jws != null) {
// Indicates communication with the service was successful.
// result.getJwsResult() contains the result data
try {
com.google.api.client.json.webtoken.JsonWebSignature sig =
JWS_PARSER.parse(jws);
validatePayload(sig.getPayload(), nonce);
} catch (IOException ex) {}
} else {
// An error occurred while communicating with the service
}
}
});
}
@tab2011
Copy link

tab2011 commented Apr 24, 2015

com.google.api.client.json.webtoken.JsonWebSignature sig = JWS_PARSER.parse(jws);
by using this, I am getting exception java.lang.IllegalArgumentException: key x5c.
Can anyone would resolve this.

@scottyab
Copy link

scottyab commented Jun 2, 2015

Hey @tab2011 I just released a helper library for safety net API that should make things a little easier. I welcome comments/feedback - https://github.com/scottyab/safetynethelper

@pylerSM
Copy link

pylerSM commented Sep 12, 2015

Have you any idea what exactly is checked? SU binary file? or what exactly.... Thanks

@Ingmicha
Copy link

Ingmicha commented Mar 3, 2021

What is the library to use JsonWebToken.Payload

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment