2

我试图在我的登录过程之前检测我的应用程序上的根设备。关于这个答案,我决定使用 SafetyNet。我像这样编辑了这段代码:

public class RootedDeviceCheckWithSafetyNetAttestation {
    public static AtomicInteger sendSafetyNetRequest(Activity context) {

        AtomicInteger rootCheck = new AtomicInteger();

        if(GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS) {
            Log.e(TAG, "The SafetyNet Attestation API is available");

            // TODO(developer): Change the nonce generation to include your own, used once value,
            // ideally from your remote server.

            String nonceData = "Safety Net Sample: " + System.currentTimeMillis();
            ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
            Random mRandom = new SecureRandom();

            byte[] bytes = new byte[24];
            mRandom.nextBytes(bytes);
            try {
                byteStream.write(bytes);
                byteStream.write(nonceData.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }

            byte[] nonce = byteStream.toByteArray();

            SafetyNetClient client = SafetyNet.getClient(context);
            Task<SafetyNetApi.AttestationResponse> task = client.attest(nonce, MY-API-KEY);

            task.addOnSuccessListener(context, attestationResponse -> {


                /*
                       TODO(developer): Forward this result to your server together with
                       the nonce for verification.
                       You can also parse the JwsResult locally to confirm that the API
                       returned a response by checking for an 'error' field first and before
                       retrying the request with an exponential backoff.
                       NOTE: Do NOT rely on a local, client-side only check for security, you
                       must verify the response on a remote server!
                      */

                String jwsResult = attestationResponse.getJwsResult();

                Log.e(TAG, "Success! SafetyNet result:\n" + jwsResult + "\n");

                if (jwsResult == null) {
                    Log.e(TAG, "jwsResult Null");

                }
                final String[] jwtParts = jwsResult.split("\\.");

                if (jwtParts.length == 3) {
                    String decodedPayload = new String(Base64.decode(jwtParts[1], Base64.DEFAULT));
                    try {
                        JSONObject jsonObject = new JSONObject(decodedPayload);
                        //Toast.makeText(context, "ctsProfileMatch:" + jsonObject.getString("ctsProfileMatch")+","+"basicIntegrity:" + jsonObject.getString("basicIntegrity"), Toast.LENGTH_SHORT).show();
                        if((jsonObject.getString("ctsProfileMatch").equals("false")) && (jsonObject.getString("basicIntegrity").equals("false"))){
                            rootCheck.set(4);
                        }
                        else{
                            rootCheck.set(1);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                        rootCheck.set(2);
                    }
                    //Toast.makeText(context, decodedPayload, Toast.LENGTH_SHORT).show();
                    //Log.e(TAG, "decodedPayload :     " + decodedPayload);
                }


            });

            task.addOnFailureListener(context, e -> {
                // An error occurred while communicating with the service.
                String mResult = null;
                rootCheck.set(5);

                if (e instanceof ApiException) {
                    // An error with the Google Play Services API contains some additional details.
                    ApiException apiException = (ApiException) e;

                    Log.e(TAG, "Error: " +
                            CommonStatusCodes.getStatusCodeString(apiException.getStatusCode()) + ": " +
                            apiException.getStatusMessage());
                    Toast.makeText(context, "Error: " +
                            CommonStatusCodes.getStatusCodeString(apiException.getStatusCode()) + ": " +
                            apiException.getStatusMessage(), Toast.LENGTH_LONG).show();
                } else {
                    // A different, unknown type of error occurred.
                    Log.e(TAG, "ERROR! " + e.getMessage());
                    Toast.makeText(context, "ERROR! " + e.getMessage(), Toast.LENGTH_LONG).show();
                }

            });

        } else {
            Log.e(TAG, "Prompt user to update Google Play services.");
            rootCheck.set(3);

        }
        return rootCheck;
    }
}

当我尝试在模拟器或有根设备上时,我可以看到我的rootCheck变量变成4了我用代码编写的。

问题是; 在真实手机中,第一次登录时,我的代码也可以检测到有根设备。但是,如果我关闭应用程序并从后台终止并再次重新打开,我会看到我的代码给出了这个 toast Error: CANCELLED: null,所以我看到了那个rootCheck变量5,这意味着跳转task.addOnFailureListenerif (e instanceof ApiException). 这个问题在有根和正常设备上引起,没关系。

问题是什么?你能帮助我吗 ?

4

0 回答 0