/// <summary> /// Verification device information required for positive submissions /// </summary> /// <returns>Device Verification Payload</returns> private static async Task <string> GetSafetyNetAttestationAsync(byte[] nonce) { using var client = SafetyNetClass.GetClient(Android.App.Application.Context); using var response = await client.AttestAsync(nonce, AppSettings.Instance.AndroidSafetyNetApiKey); return(response.JwsResult); }
public async System.Threading.Tasks.Task AttestateAsync(Activity activity) { try { var api = RestService.For <ApiService>("https://devenir.andrewkir.ru"); JSONObject obj = new JSONObject(); timestamp = DateTime.Now.Ticks.ToString(); device_id = Secure.GetString(activity.ContentResolver, Secure.AndroidId); obj.Put("timestamp", timestamp); obj.Put("device_id", device_id); var response = await api.GetNonce(obj.ToString()); if (response == null) { AttestationResultEvent?.Invoke(false, activity.GetString(Resource.String.noInternetException)); return; } if (response.IsSuccessStatusCode) { string nonce = response.Content; if (GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(Application.Context) == ConnectionResult.Success) { // The SafetyNet Attestation API is available. SafetyNetClient client = SafetyNetClass.GetClient(activity); var task = client.Attest(Encoding.ASCII.GetBytes(nonce), activity.Resources.GetString(Resource.String.api_safetyNetKey)) .AddOnSuccessListener(activity, new OnSuccessListener(activity, timestamp, this)) .AddOnFailureListener(activity, new OnFailureListener(activity, this)); } else { // Prompt user to update Google Play services AttestationResultEvent?.Invoke(false, activity.GetString(Resource.String.attestationGooglePlayException)); } return; } else { AttestationResultEvent?.Invoke(false, activity.GetString(Resource.String.serverException) + $"failed with nonce"); return; } } catch (HttpRequestException ex) { AttestationResultEvent?.Invoke(false, activity.GetString(Resource.String.serverException) + $"https exception {ex}"); } catch (Exception ex) { AttestationResultEvent?.Invoke(false, activity.GetString(Resource.String.unexpectedException)); } }
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, this) .AddApi(SafetyNetClass.API) .Build(); buttonCheck.Click += async delegate { var api = SafetyNetClass.GetClient(this); var nonce = Nonce.Generate(); // Should be at least 16 bytes in length. var r = await api.AttestAsync(nonce, DEVELOPERS_CONSOLE_API_KEY); if (r != null && !string.IsNullOrEmpty(r.JwsResult)) { // Store for future verification with google servers attestationResponse = 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 attestationResponse.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(); } }; }