【发布时间】:2021-08-18 17:57:26
【问题描述】:
我遇到了关于 google 安全网 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('"');
}
【问题讨论】:
-
您可以尝试集成Dotfuscator进行运行检查,以检测应用是否在root设备或模拟器上运行,请参考docs.microsoft.com/en-us/archive/msdn-magazine/2018/may/…。
-
我想改用safetynet(google play sevice api)
-
会不会是死锁场景?我注意到您正在为正在开始的任务调用
.Result,而您没有在等待的呼叫中添加.ConfigureAwait(false)。 -
你能不能让 OnCreate
async void和awaitRunSafetyNetCheck调用。此外,在RunSafetyNetCheck方法中的等待调用中添加.ConfigureAwait(false)。 -
@Cheesebaron 我试过你上面提到的。但仍然没有得到任何回应。可能出了什么问题?
标签: xamarin xamarin.forms safetynet safetynet-api