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
}
}
});
}
@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