我遇到了谷歌安全网 api 证明响应的问题。即使我向“client.AttestAsync()”方法提供了安全网客户端、nonce 和 apikey,它也不会返回 SafetyNetApiAttestationResponse。下面的代码可能有什么问题?如何获得证明响应以检查 android 设备是在模拟器上运行还是在 xamarin 形式的 root 设备上运行?
protected override void OnCreate(Bundle bundle)
{
Instance = this;
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
BackgroundAggregator.Init(this);
base.OnCreate(bundle);
DependencyService.Register<ToastNotification>();
ToastNotification.Init(this);
Rg.Plugins.Popup.Popup.Init(this);
global::Xamarin.Forms.Forms.Init(this, bundle);
micService = DependencyService.Resolve<IMicrophoneService>();
if (GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(this, 13000000) == ConnectionResult.Success)
{
SafetyNetClient client = Android.Gms.SafetyNet.SafetyNetClass.GetClient(this);
byte[] nonce = Android.Gms.SafetyNet.Nonce.Generate();
bool valid = Task.Run(() => RunSafetyNetCheck(client, nonce)).Result;
if (!valid)
LoadApplication(new App());
else
Toast.MakeText(this, "Failed response validation with Google!", ToastLength.Short).Show();
}
else
{
Toast.MakeText(this, "Update Google Play services.!", ToastLength.Short).Show();
}
}
private async Task<bool> RunSafetyNetCheck(SafetyNetClient client, byte[] nonce)
{
bool valid = false;
SafetyNetApiAttestationResponse r = await client.AttestAsync(nonce, apiKey);
if (r != null && !string.IsNullOrEmpty(r.JwsResult))
{
attestationResponse = r;
var decodedResult = r.DecodeJwsResult(nonce);
string error = null;
if (VerifyAttestResponse(decodedResult, nonce, out error))
{
valid = await attestationResponse.ValidateWithGoogle(apiKey);
}
else
{
Toast.MakeText(this, "Compatibility Failed: " + error, ToastLength.Long).Show();
}
}
else
{
Toast.MakeText(this, "Failed to Check Compatibility", ToastLength.Long).Show();
}
return valid;
}
private bool VerifyAttestResponse(string data, byte[] sentNonce, out string errorMessage)
{
errorMessage = null;
var json = JsonObject.Parse(data);
var error = GetValue(json, "error");
var nonce = GetValue(json, "nonce");
var timestampMs = GetValue(json, "timestampMs");
var apkPackageName = GetValue(json, "apkPackageName");
var apkCertDigestSha256 = GetValue(json, "apkCertificateDigestSha256");
var apkDigestSha256 = GetValue(json, "apkDigestSha256");
var ctsProfileMatch = GetValue(json, "ctsProfileMatch") == "true";
if (!string.IsNullOrEmpty(error))
{
errorMessage = "Response Contained an Error: " + error;
return false;
}
var sentNonceStr = Convert.ToBase64String(sentNonce);
if (!nonce.Equals(sentNonceStr))
{
errorMessage = "Nonce's do no match";
return false;
}
if (PackageName != apkPackageName)
{
errorMessage = "Package Names do not match";
return false;
}
if (!ctsProfileMatch)
{
errorMessage = "CTS Profile was false";
return false;
}
return true;
}
private string GetValue(JsonValue json, string field)
{
if (!json.ContainsKey(field))
return string.Empty;
return json[field].ToString().Trim('"');
}