protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);

            // Set our view from the "main" layout resource
            SetContentView (Resource.Layout.Main);

            buttonCheck = FindViewById<Button> (Resource.Id.buttonCheck);
            buttonVerify = FindViewById<Button> (Resource.Id.buttonVerify);
            buttonVerify.Enabled = false;

            googleApiClient = new GoogleApiClient.Builder (this)
                .EnableAutoManage (this, 1, result => {
                    Toast.MakeText (this, "Failed to connect to Google Play Services", ToastLength.Long).Show ();
                })
                .AddApi (SafetyNetClass.API)
                .Build ();

            buttonCheck.Click += async delegate {
                
                var nonce = Nonce.Generate (); // Should be at least 16 bytes in length.
                var r = await SafetyNetClass.SafetyNetApi.AttestAsync (googleApiClient, nonce);

                if (r.Status.IsSuccess) {

                    // Store for future verification with google servers
                    attestationResult = r;

                    // Get the JSON from the JWS result by decoding
                    var decodedResult = r.DecodeJwsResult (nonce);

                    string error = null;

                    // Try and verify the body of the response
                    if (VerifyAttestResponse (decodedResult, nonce, out error)) {
                        Toast.MakeText (this, "Compatibility Passed!", ToastLength.Long).Show ();
                        buttonVerify.Enabled = true;
                    } else {
                        Toast.MakeText (this, "Compatibility Failed: " + error, ToastLength.Long).Show ();
                    }
                } else {
                    // Error
                    Toast.MakeText (this, "Failed to Check Compatibility", ToastLength.Long).Show ();
                }
            };


            buttonVerify.Click += async delegate {
               
                // Validate the JWS response with Google to ensure it came from them
                var valid = await attestationResult.ValidateWithGoogle (DEVELOPERS_CONSOLE_API_KEY);

                if (valid)
                    Toast.MakeText (this, "Successfully validated response with Google!", ToastLength.Short).Show ();
                else
                    Toast.MakeText (this, "Failed response validation with Google!", ToastLength.Short).Show ();
            };
        }
Example #2
0
        public static async Task <bool> ValidateWithGoogle(this ISafetyNetApiAttestationResult result, string validationApiKey)
        {
            const string url = "https://www.googleapis.com/androidcheck/v1/attestations/verify?key=";

            var http    = new HttpClient();
            var jsonReq = "{ \"signedAttestation\": \"" + result.JwsResult + "\" }";
            var content = new StringContent(jsonReq, Encoding.Default, "application/json");

            var response = await http.PostAsync(url + validationApiKey, content);

            var data = await response.Content.ReadAsStringAsync();

            response.EnsureSuccessStatusCode();

            var json = JsonObject.Parse(data);

            if (json.ContainsKey("isValidSignature"))
            {
                return(json ["isValidSignature"].ToString().Trim('"').Equals("true"));
            }

            return(false);
        }
Example #3
0
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            buttonCheck          = FindViewById <Button> (Resource.Id.buttonCheck);
            buttonVerify         = FindViewById <Button> (Resource.Id.buttonVerify);
            buttonVerify.Enabled = false;

            googleApiClient = new GoogleApiClient.Builder(this)
                              .EnableAutoManage(this, 1, result => {
                Toast.MakeText(this, "Failed to connect to Google Play Services", ToastLength.Long).Show();
            })
                              .AddApi(SafetyNetClass.API)
                              .Build();

            buttonCheck.Click += async delegate {
                var nonce = Nonce.Generate();  // Should be at least 16 bytes in length.
                var r     = await SafetyNetClass.SafetyNetApi.AttestAsync(googleApiClient, nonce);

                if (r.Status.IsSuccess)
                {
                    // Store for future verification with google servers
                    attestationResult = r;

                    // Get the JSON from the JWS result by decoding
                    var decodedResult = r.DecodeJwsResult(nonce);

                    string error = null;

                    // Try and verify the body of the response
                    if (VerifyAttestResponse(decodedResult, nonce, out error))
                    {
                        Toast.MakeText(this, "Compatibility Passed!", ToastLength.Long).Show();
                        buttonVerify.Enabled = true;
                    }
                    else
                    {
                        Toast.MakeText(this, "Compatibility Failed: " + error, ToastLength.Long).Show();
                    }
                }
                else
                {
                    // Error
                    Toast.MakeText(this, "Failed to Check Compatibility", ToastLength.Long).Show();
                }
            };


            buttonVerify.Click += async delegate {
                // Validate the JWS response with Google to ensure it came from them
                var valid = await attestationResult.ValidateWithGoogle(DEVELOPERS_CONSOLE_API_KEY);

                if (valid)
                {
                    Toast.MakeText(this, "Successfully validated response with Google!", ToastLength.Short).Show();
                }
                else
                {
                    Toast.MakeText(this, "Failed response validation with Google!", ToastLength.Short).Show();
                }
            };
        }
Example #4
0
 public static string DecodeJwsResult(this ISafetyNetApiAttestationResult result, byte[] originalNonce)
 {
     return(JWT.JsonWebToken.Decode(result.JwsResult, originalNonce));
 }