Last active
March 3, 2021 20:24
-
-
Save ganadist/2af47d422ca6f9d30e8d to your computer and use it in GitHub Desktop.
SafetyNet example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} | |
}); | |
} |
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
Have you any idea what exactly is checked? SU binary file? or what exactly.... Thanks