One, foreword

This is the fifth article in our series exploring the art of Android SDK development. This paper introduces some knowledge of SDK development security, including resource integrity, storage security, permission check, transmission security, code confusion and so on. Explore security best practices for SDK development by protecting the SDK with basic security configurations.

Anti-bar description: I agree that there is no absolute security at the front end, basically most of the security policies we openly talk about can be circumvented, but this cannot be the reason for us to ignore security.

Series of articles:

Android SDK Development Art Exploration (1) Introduction and Design

(2) Exception or ErrorCode

Android SDK development art exploration (iii) initialization

Android SDK development art exploration (4) personalized configuration

Android SDK development art exploration (5) security and verification

Android SDK development art exploration (6) compression and optimization

Android SDK development art exploration (vii) Dependency principles and packaging methods

Second, security overview

Third, resource security

3.1 integrity check

SDK resource integrity check refers to the integrity check of AAR package during SDK development. In fact, to check the integrity and validity of resources, it is usually to check the summary of their files. The same is true for SDK packages, where a summary of the file can be published along with an AAR for verification purposes.

Another way to detect resources from SDK code is also briefly introduced here. As we all know, AAR is completely incorporated into APK at compile time, so the idea of validating AAR summaries is broken. However, we can verify AAR resources, such as files in raw and assets directories. The files in these two directories are not compressed during compilation. Therefore, the file content and summary are not changed before and after compilation. Therefore, the files are suitable for resource verification.

As for the summary verification scheme, it can be done simply in the Java level, or in so. The timing and strategy of the verification are more choices, which will not be expanded here.

3.2. Be alert to security problems caused by resource coverage

Android Studio merges resources in the Library module with those in the Application module. Resources in the App Module will override resources in the Library Module with the same name. Because of this feature, we have to protect SDK resources from unexpected overwrites that can lead to inconsistent software behavior.

The resources we mentioned mainly include the common RES, all files in assets directory. When naming files or resources, you must add unique prefixes or other unique naming schemes.

Every coin has two sides, and this feature also provides a way for us to replace SDK resources and personalize them.

Four, storage security

In this aspect of safe storage, mainly test the consciousness of developers, see here friends might as well check the old code at hand, maybe there is sensitive information plaintext storage, direct streaked problem.

4.1. SP secure storage

SharedPreferences Saves data in the XML file format. The file is located in the /data/data//shared_prefs/ directory. If you directly store the account password or personal sensitive information in the file, you can easily obtain the file after the root of the mobile phone. Therefore, storage as far as possible to consider a simple layer of encryption logic. Whether it’s SharedPreferences or databases, avoid plain-text sensitive data stores.

In addition, when SharedPreferences store some configuration information, configure the access permission, such as the private access permission MODE_PRIVATE, to prevent the configuration information from being tampered with.

4.2. SO Safe storage

Since Java is an interpreted language, Java obfuscation does not obfuscate constants. But we inevitably store some key pairs in the front end, so how can we store them safely? It is recommended to store the key in SO, and the encryption and decryption logic and even the transmission logic should be placed in SO to better protect the code logic.

Before also wrote a simple article, interested can refer to the JNI preliminary sensitive information protection

5. Transmission security

5.1 Network security Configuration

This feature gives applications the flexibility to customize their Https network security Settings in a secure declarative profile without modifying application code to meet higher security requirements.

Configure networkSecurityConfig in Androidmanifest.xml:


      
<manifest . >
    <application android:networkSecurityConfig="@xml/network_security_config"
                    . >.</application>
</manifest>
Copy the code

The network_security_config file is as follows:


      
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">example.com</domain>
        <trust-anchors>
            <certificates src="@raw/my_ca"/>
        </trust-anchors>
    </domain-config>
</network-security-config>
Copy the code

Add a self-signed or non-public CA certificate to RES/RAW/MY_CA in PEM or DER format. Thinking back to the horror of hearing the results of the penetration test years ago, boy, faked a certificate… Android7.0 does not trust manually installed certificates.

For more details and functions in this section, see the official network Security Configuration documents

5.2 Safety environment testing

We said here mentioned security environment mainly refers to the environment that may affect our business logic, such as hanging VPN agent, Root mobile phone/installed Xposed, application is more open, simulator environment…

5.2.1 VPN agent Detection

Check whether VPN is enabled on the current connected network

// Check whether the system is using a VPN connection
public boolean isVpnOn(Context context) {
    boolean isVpnOn = false;
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
        Network activeNetwork = connectivityManager.getActiveNetwork();
        NetworkCapabilities caps = connectivityManager.getNetworkCapabilities(activeNetwork);
        isVpnOn = caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
    }else {
        isVpnOn = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_VPN).isConnectedOrConnecting();
    }
    Log.i(TAG, "Is VPN On: " + isVpnOn);
    return isVpnOn;
}
Copy the code

5.2.2 Root/Xposed/ anti-debugging/application multi-open/simulator detection

About Root/Xposed/ anti debugging/application multi open/simulator detection method, here recommend a good third-party library EasyProtector specific API is not posted here, refer to the author’s project.

Confusion and configuration

6.1. Manual integration

Usually when we connect to a third-party SDK, we have an obfuscated configuration. In the same way, we can refer to this kind of design when publishing the SDK and provide the code configuration that does not need to be confused in the SDK, which can be integrated into the docking document.

6.2 Built-in SDK

In order to improve the access experience, can the SDK obfuscated configuration be packaged into the AAR and the project automatically configure the SDK obfuscated file? The answer is yes, you can specify the consumerProguardFiles property, customize the obtruse rules introduced, and package the *. Pro file into the AAR, which will automatically merge the configuration file when the project is packaged. It is worth noting that this property only works for Library, not app.

The consumerProguardFiles configuration is as follows:

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"

    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        consumerProguardFiles "proguard-rules.pro"// Package the Library obfuscation configuration into the AAR to participate in obfuscation at app build time
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources false
            signingConfig signingConfigs.release
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            minifyEnabled false
            shrinkResources false
            signingConfig signingConfigs.release
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}}Copy the code

6.3 The pits of confusion

In Android Studio 4.x, a new library Module will automatically create two ***rules.pro files, where consumer-rules.pro, Automatically referenced by the consumerProguardFiles under defaultConfig; Proguard-rules. pro, automatically referenced by proguardFiles under buildType.

So what’s the difference between the two? Why separate the two files? After full verification, the conclusion is as follows:

1. The *. Pro file configured by consumerProguardFiles under defaultConfig will exist as proGuard. TXT when the Library Module is packaged as an AAR and will participate in the compilation of the App that integrates this ARR. Do not participate in the compilation of the Library Module as an AAR;

2. BuildType proguardFiles set to *. Pro files and library Module package aar compilation process, only for this module compilation confusion process.

In practice, change the *. Pro file configured by consumerProguardFiles directly to proGuard-rules.pro, which roughly resolves aar compilation confusion and APK compilation confusion.

However, it is important to note that in accordance with the principle of minimum availability in our SDK development design, obfuscating rules should be added with care, if not necessary, to avoid interfering with the normal obfuscating of integrating the AAR project.

Seven, conclusion

This article mainly introduces some KNOWLEDGE of SDK security and verification. Security is a kind of consciousness, the difficult thing is not security, is not consciousness. As mentioned in the beginning, there is no absolute security at the front end, but security should not only rely on the front end, it should be multi-level, system-level security under multi-terminal coordination. For developers, something should be done. After all, one more line of defense means a little more security. A developer should have basic safety awareness in order to avoid security incidents as much as possible.

Finally, if this document is helpful or inspiring to your development, like/follow/share three lines is the best incentive for the author to continue to create, thanks for your support!

Refer to the article

  • EasyProtector
  • Aandroid Developer

Copyright Notice:

This article first appeared in my column AndDev Android development has been authorized to hongyang public account exclusive release.