Android HMS端末にインストールされたアプリのセキュリティを確認する方法

HMS端末にインストールされたアプリに悪意があるアプリが含まれているかどうかを検出する方法を紹介します。

# 利用ライブラリ
[Safety Detect](https://developer.huawei.com/consumer/jp/hms/huawei-safetydetectkit/)

### 対応端末
すべてのHMS端末

### 対応OS
EMUI 5.0以上

# 実装手順

## 前準備
(1) Huaweu Developerを登録します。

(2) AppGallery Connectでアプリのプロジェクトを登録します。
<img width="600" alt="スクリーンショット 2020-10-01 155726.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/7ad86f57-75ef-2aa1-7f8a-89ba53ec0ae1.png">
<img width="600" alt="スクリーンショット 2020-10-01 155747.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/910d9b63-0bf4-90fd-3aba-168b4eb26310.png">
<img width="600" alt="スクリーンショット 2020-10-01 155822.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/890cd9ee-09ad-3e72-d9fb-7b1d95d48c45.png">
<img width="600" alt="スクリーンショット 2020-10-01 155911.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/50d68b1d-4b5f-d185-2ecc-3b03c4175ad7.png">
<img width="600" alt="スクリーンショット 2020-10-01 155946.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/25cf901a-7e9f-fbde-9eeb-63504bb9a821.png">

(3) keytoolで生成したSHA256をAppGallery Connectのアプリプロジェクトに登録します。
<img width="600" alt="スクリーンショット 2020-10-01 160111.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/60cc348f-e029-8b02-8291-b16df40dd33d.png">

(4) agconnect-services.jsonをダウンロードし、appフォルダに配置します。
<img width="600" alt="スクリーンショット 2020-10-01 161111.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/f50eb1bb-6cbd-4575-0cb3-8f40b19c871d.png">
<img width="400" alt="スクリーンショット 2020-10-01 162011.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/74e4218e-ea0d-fbbf-6cc3-134ff40d9c0f.png">

(5) Safety Detectを有効にします。
<img width="600" alt="スクリーンショット 2020-10-01 160111.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/da6d96a1-4458-7ab7-45ae-f28df279b750.png">

## HMS SDKを導入
(1) プロジェクトのbuild.gradleを開き、mavenとclasspathを追加します。
<img width="400" alt="スクリーンショット 2020-10-01 162820.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/7ee345a1-2c6d-9857-deed-776060a09de4.png">

```gradle:build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = "1.3.72"
    repositories {
        google()
        jcenter()

        // こちらの行を追加
        maven {url 'http://developer.huawei.com/repo/'}
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.0.1"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files

        // こちらの行を追加
        classpath 'com.huawei.agconnect:agcp:1.3.1.300'
    }
}

allprojects {
    repositories {
        google()
        jcenter()

        // こちらの行を追加
        maven { url 'http://developer.huawei.com/repo/' }
    }
}
```

(2) モジュールのbuild.gradleを開き、次のようにを追加します。
<img width="200" alt="スクリーンショット 2020-10-01 162842.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/7cd74ac6-a36a-dbdd-30ea-fb24c14f0408.png">

```gradle:build.gradle
plugins {
    id 'com.android.application'
    id 'kotlin-android'

    // こちらの行を追加
    id 'com.huawei.agconnect'
}

android {
    // signingConfigsを追加
    signingConfigs {
        debug {
            storePassword 'My password'
            keyAlias 'My keyAlias'
            keyPassword 'My password'
            storeFile file('My keystore file.jks')
            v1SigningEnabled true
            v2SigningEnabled true
        }
        release {
            storePassword 'My password'
            keyAlias 'My keyAlias'
            keyPassword 'My password'
            storeFile file('My keystore file.jks')
            v1SigningEnabled true
            v2SigningEnabled true
        }
    }

    buildTypes {
        release {
            // signingConfigを追加
            signingConfig signingConfigs.release

            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }

        debug {
            // signingConfigを追加
            signingConfig signingConfigs.debug

            debuggable true
        }
    }

    buildFeatures {
        dataBinding true
    }
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.6.0'
    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    // こちらの１行を追加
    implementation 'com.huawei.hms:safetydetect:6.3.0.301'
}
```

(3) proguard-rules.proを開き、次のようにを追加します。
<img width="400" alt="スクリーンショット 2020-10-01 162901.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/01ff236e-58c6-0000-165a-99daa78f64e8.png">

```java:proguard-rules.pro
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.huawei.hianalytics.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
```

## ライブラリの使用

```kotlin
private fun getMaliciousApps() {
    SafetyDetect.getClient(this)
            .maliciousAppsList
            .addOnSuccessListener { maliciousAppsListResp ->
                val appsDataList: List<MaliciousAppsData> = maliciousAppsListResp.maliciousAppsList
                if (maliciousAppsListResp.rtnCode == CommonCode.OK) {
                    if (appsDataList.isEmpty()) {
                        val text = "No known potentially malicious apps are installed."
                        Toast.makeText(this!!.applicationContext, text, Toast.LENGTH_SHORT).show()
                    } else {
                        for (maliciousApp in appsDataList) {
                            Log.e(TAG, "Information about a malicious app:")
                            Log.e(TAG, "  APK: " + maliciousApp.apkPackageName)
                            Log.e(TAG, "  SHA-256: " + maliciousApp.apkSha256)
                            Log.e(TAG, "  Category: " + maliciousApp.apkCategory)
                        }
                    }
                } else {
                    val msg = ("Get malicious apps list failed! Message: " + maliciousAppsListResp.errorReason)
                    Log.e(TAG, msg)
                }
            }
            .addOnFailureListener { error ->
                error?.printStackTrace()
            }
}
```

appsDataListに悪意があるアプリのリストが入っています。

# GitHub
[https://github.com/Rei2020GitHub/MyPublicProject/tree/master/SafetyDetectDemo](https://github.com/Rei2020GitHub/MyPublicProject/tree/master/SafetyDetectDemo)

# 参考
* HMS：[https://developer.huawei.com/consumer/jp/](https://developer.huawei.com/consumer/jp/)
* Safety Detectの紹介：[https://developer.huawei.com/consumer/jp/hms/huawei-safetydetectkit/](https://developer.huawei.com/consumer/jp/hms/huawei-safetydetectkit/)
* Safety Detectのドキュメント：[https://developer.huawei.com/consumer/en/doc/development/Security-Guides/appscheck-0000001050154380](https://developer.huawei.com/consumer/en/doc/development/Security-Guides/appscheck-0000001050154380)
* Huawei Developers：[https://forums.developer.huawei.com/forumPortal/en/home](https://forums.developer.huawei.com/forumPortal/en/home)
* Facebook Huawei Developersグループ：[https://www.facebook.com/Huaweidevs/](https://www.facebook.com/Huaweidevs/)