Overview

The Safety Detect provides system integrity check (SysIntegrity), app security check (AppsCheck), malicious URL check (URLCheck), and fake user detection (UserDetect), helping you prevent security threats to your app.
SysIntegrity API: Checks whether the device running your app is secure, for example, whether it is rooted.
AppsCheck API: Obtains a list of malicious apps.
URLCheck API: Determines the threat type of a specific URL.
UserDetect API: Checks whether your app is interacting with a fake user.

What You Will Create

In this codelab, you will use a created demo project to call the SysIntegrity, AppsCheck, URLCheck, and UserDetect APIs. Through the demo project, you will:
SysIntegrity:

AppsCheck:

URLCheck:

UserDetect:

What You Will Learn

Hardware Requirements

Software Requirements

HUAWEI HMS Core integration requires the following preparations

For details, see the HUAWEI HMS Core Integration Preparation.

Enabling the Service

  1. Go to Console > AppGallery Connect > My apps, click your app, and go to Develop > Overview > Manage APIs.
  2. Enable the Safety Detect service.

Add the AppGallery Connect configuration file of your app

  1. Sign in to AppGallery Connect and select My apps. Go to Develop > Overview > App information, click "agconnect-service.json" to download the configuration file.
  2. Move the downloaded agconnect-services.json file to the app root directory of your Android Studio project.

Add the dependencies of HMS SDK

  1. Open the build.gradle file in the app directory of your project.
  2. Configure compile dependencies in dependencies.
    dependencies { // Add the following line implementation 'com.huawei.hms:safetydetect:4.0.0.300' }

Configuring Obfuscation Scripts

1.Before building the APK, configure obfuscation scripts to prevent the HMS SDK from being obfuscated. If obfuscation arises, the HMS SDK may not function properly.

Open the obfuscation configuration file of your project.

Add configurations to exclude the HMS SDK from obfuscation.

-ignorewarning -keepattributes *Annotation* -keepattributes Exceptions -keepattributes InnerClasses -keepattributes Signature -keepattributes SourceFile, LineNumberTable -keep class com.hianalytics.android.** {*; } -keep class com.huawei.updatesdk.** {*; } -keep class com.huawei.hms.** {*; }

2.If you have used AndResGuard, add it to the whitelist in the obfuscation script file.

"R.string.hms*", "R.string.connect_server_fail_prompt_toast", "R.string.getting_message_fail_prompt_toast", "R.string.no_available_network_prompt_toast", "R.string.third_app_*", "R.string.upsdk_*", "R.layout.hms*", "R.layout.upsdk_*", "R.drawable.upsdk*", "R.color.upsdk*", "R.dimen.upsdk*", "R.style.upsdk*"

3.Click Sync now to synchronize the project.

SysIntegrity

To call the SysIntegrity API, perform the following steps:

  1. Obtain a nonce value.
  2. Request the SysIntegrity API of Safety Detect.
  3. Verify the check result (signature, certificate chain, and domain name) on your server.

Obtain a nonce value

When calling the SysIntegrity API of Safety Detect, you must transfer a nonce value that will be contained in the check result. You can check the nonce value to determine whether the returned result corresponds to your request and does not encounter replay attacks.
A nonce value must contain at least 24 bytes and can only be used once. It is recommended that the nonce value be derived from data sent to your server. For example, you can use the user name and the current timestamp as the nonce value.

Request the SysIntegrity API of Safety Detect

The SysIntegrity API has two input parameters. The first one is the nonce value, and the other is appId. Because you have created an app during development preparations, you can obtain appId on HUAWEI Developer as described in the "Configuring a Signing Certificate Fingerprint" section. Transfer appId to the API as the second input parameter.

private void invokeSysIntegrity() { SafetyDetectClient mClient = SafetyDetect.getClient(getApplicationContext()); // TODO(developer): Change the nonce generation to include your own, used once value, // ideally from your remote server. byte[] nonce = ("Sample" + System.currentTimeMillis()).getBytes(); Task task = mClient.sysIntegrity(nonce,"3*******"); task.addOnSuccessListener(new OnSuccessListener<SysIntegrityResp>() { @Override public void onSuccess(SysIntegrityResp response) { // Indicates communication with the service was successful. // Use response.getResult() to get the result data. String jwsStr = response.getResult(); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { // An error occurred while communicating with the service. if (e instanceof ApiException) { // An error with the HMS API contains some // additional details. ApiException apiException = (ApiException) e; // You can retrieve the status code using // the apiException.getStatusCode() method. Log.e(TAG, "Error: " + SafetyDetectStatusCodes.getStatusCodeString(apiException.getStatusCode()) + ": " + apiException.getStatusMessage()); } else { // A different, unknown type of error occurred. Log.e(TAG, "ERROR:" + e.getMessage()); } } }); }

Server

It is recommended that the JWS-format result be handled in the following process. The certificate and signature verification needs to be implemented on the background server of your app.

For details about the verification logic, download the sample code

SafetyDetect-SysIntegrity-Sample

Test

Install the sample APK to be tested and call the SysIntegrity API.

AppsCheck

Client

You can directly call getMaliciousApps of the AppsCheck API to obtain a list of malicious apps:

private void invokeGetMaliciousApps() { SafetyDetectClient appsCheckClient = SafetyDetect.getClient(MainActivity.this); Task task = appsCheckClient.getMaliciousAppsList(); task.addOnSuccessListener(new OnSuccessListener<MaliciousAppsListResp>() { @Override public void onSuccess(MaliciousAppsListResp maliciousAppsListResp) { // Indicates communication with the service was successful. // Use resp.getMaliciousApps() to get malicious apps data. List<MaliciousAppsData> appsDataList = maliciousAppsListResp.getMaliciousAppsList(); // Indicates get malicious apps was successful. if (maliciousAppsListResp.getRtnCode() == CommonCode.OK) { if (appsDataList.isEmpty()) { // Indicates there are no known malicious apps. Log.i(TAG, "There are no known potentially malicious apps installed."); } else { Log.i(TAG, "Potentially malicious apps are installed!"); for (MaliciousAppsData maliciousApp : appsDataList) { Log.i(TAG, "Information about a malicious app:"); // Use getApkPackageName() to get APK name of malicious app. Log.i(TAG, "APK: " + maliciousApp.getApkPackageName()); // Use getApkSha256() to get APK sha256 of malicious app. Log.i(TAG, "SHA-256: " + maliciousApp.getApkSha256()); // Use getApkCategory() to get category of malicious app. // Categories are defined in AppsCheckConstants Log.i(TAG, "Category: " + maliciousApp.getApkCategory()); } } } else { Log.e(TAG, "getMaliciousAppsList fialed: " + maliciousAppsListResp.getErrorReason()); } } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { // An error occurred while communicating with the service. if (e instanceof ApiException) { // An error with the HMS API contains some // additional details. ApiException apiException = (ApiException) e; // You can retrieve the status code using the apiException.getStatusCode() method. Log.e(TAG, "Error: " + SafetyDetectStatusCodes.getStatusCodeString(apiException.getStatusCode()) + ": " + apiException.getStatusMessage()); } else { // A different, unknown type of error occurred. Log.e(TAG, "ERROR: " + e.getMessage()); } } }); }

Test

Click GET HARMFUL APPS LIST:

URLCheck

To call the URLCheck API, perform the following steps:

  1. Initialize the URLCheck API.
  2. Request for URL check.
  3. Close the URL check session.
  4. Process the result code.

Initializing the URLCheck API

Before using the URLCheck API, you must call the initUrlChecker() method to initialize the API. The sample code is as follows:

SafetyDetectClient client = SafetyDetect.getClient(getActivity()); client.initUrlCheck();

Requesting for URL Check

Specify the types of concerned threats as the input parameter of the URLCheck API. Constants in the UrlCheckerThreat class include the threat types that can currently be addressed.

package com.huawei.hms.safetydetect; public class UrlCheckerThreat { /** * URLs of this type are marked as URLs of pages containing potentially malicious apps (such as home page tampering URLs, Trojan-infected URLs, and malicious app download URLs). */ public static final int MALWARE = 1; /** * URLs of this type are marked as phishing and spoofing URLs. */ public static final int PHISHING = 3; }

Initiate a URL check request. The URL to be checked contains the protocol, host, and path but does not contain the query parameter. The sample code is as follows:

String url = "https://developer.huawei.com/consumer/cn/"; SafetyDetect.getClient(this).urlCheck(url, appId, UrlCheckerThreat.MALWARE, UrlCheckerThreat.PHISHING) .addOnSuccessListener(this, new OnSuccessListener<SafetyDetectApi.URLCheckerResponse>() { @Override public void onSuccess(SafetyDetectApi.URLCheckerResponse urlResponse) { // Indicates that the communication with the service is successful and the detected threat is identified.[c(1] if (urlResponse.getDetectedThreats().isEmpty()) { // No threat exists. } else { // Threats exist. } } }) .addOnFailureListener(this, new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // An error occurs during communication with the service. if (e instanceof ApiException) { // Huawei Mobile Services (APK) error code and corresponding error description. ApiException apiException = (ApiException) e; Log.d(TAG, "Error: " + CommonStatusCodes .getStatusCodeString(apiException.getStatusCode())); // Note: If the status code is SafetyDetectStatusCode.ERROR_URL_CHECKER_API_NOT_INITIALIZED, // you do not call the initUrlChecker() method or you have initiated a URL check request before the call is completed. // If an internal error occurs during the initialization, you need to call the initUrlChecker() method again to initialize the API. } else { // An unknown exception occurs. Log.d(TAG, "Error: " + e.getMessage()); } } });

Call the getUrlCheckerResponse () method of the URLCheckerResponse object to obtain the URL check response. The method returns List<UrlCheckerThreat> which contains a list of all detected URL threat types. If the list is empty, no threat is detected. Otherwise, you can call the getUrlCheckResult () method of UrlCheckerThreat to obtain the specific threat code. The sample code is as follows:

final EditText testRes = getActivity().findViewById(R.id.fg_call_urlResult); List<UrlCheckerThreat> list = urlCheckerResponse.getUrlCheckerResponse(); if (list.isEmpty()) { testRes.setText("ok"); } else { for (UrlCheckerThreat threat : list) { int type = threat.getUrlCheckResult(); } }

Closing the URL Check Session

If your app does not need to call the URLCheck API anymore or will not need to for a while, you can call the shutdownUrlChecker() method to close the URL check session and release relevant resources.

SafetyDetect.getClient(this).shutdownUrlChecker();

Test

Install the sample APK to be tested and call the URLCheck API.

UserDetect

The sample code consists of two parts: client and server. The client part demonstrates how to call the API and obtain a response token. The server part demonstrates how to obtain the final fake user detection result.

Calling the UserDetect API

To call the UserDetect API, perform the following steps:

  1. Call the userDetection() method of the UserDetect API to initiate a fake user detection request. The API will return a response token.
  2. Use this response token to call verify on the cloud to obtain the detection result.

Initiating a Detection Request

You need to call the userDetection method to initiate a detection request. Generally, this method is triggered when a user taps a UI control (such as a button). To call the userDetection method, perform the following steps:

  1. Transfer the applied appId as the input parameter of the method.
  2. Add the OnSuccessListener and OnFailureListener instances as listeners.
  3. Override onSuccess and onFailure to process the corresponding result.
    The sample code for calling this method is as follows:
    final Task<UserDetectResponse> task = client.userDetection(APP_ID); task.addOnSuccessListener(new OnSuccessListener() { //success to get result from userDetection API @Override public void onSuccess(Object obj) { UserDetectResponse userDetectResponse = (UserDetectResponse) obj; String responseToken = userDetectResponse.getResponseToken(); //Send the response token to your own app server,so that you can get the final result //of user detect service. Replace the verify method with your own code here. String result = verify(responseToken); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { } });

Obtaining the Detection Result

Perform the following steps on the server:

  1. Obtain an access token.
  2. Call the cloud-side API to obtain the detection result.
    The procedure is as follows:
    Obtain an access token.
    For details, please refer to Open Platform Authentication.
    Call the cloud-side API to obtain the detection result. The following is a request example:
    POST https://rms-api.cloud.huawei.com/rms/v1/userRisks/verify?appId=123456 HTTP/1.1 Content-Type: application/json;charset=utf-8 {"accessToken":"AAWWHI94sgUR2RU5_P1ZptUiwLq7W8XWJO2LxaAPuXw4_HOJFXnBlN-q5_3bwlxVW_SHeDPx_s5bWW-9DjtWZsvcm9CwXe1FHJg0u-D2pcQPcb3sTxDTJeiwEb9WBPl_9w","response":"bc9d6e73-b422-4d7c-8464-2a8b5ad5b525" }

For details about the request API, please refer to the API reference.

Test

Install the sample APK to be tested and call the UserDetect API.

Download the full functional sample code.

safetydetect android sample

Well done. You have successfully completed this codelab and learned:

For more information, click the following link:
Related Documents

You can download the source code in github.com/Huawei/Consumer/tree/master/Codelabs/SafetyDetect

You can also click the button below to download the source code.

safetydetect android sample

Code copied