HomeOur Team
Nâng cao bảo mật ứng dụng bằng Android NDK
Tips / Tricks
Nâng cao bảo mật ứng dụng bằng Android NDK
binh.tran
binh.tran
March 26, 2021
4 min

Nâng cao bảo mật ứng dụng bằng Android NDK

Có người từng nói “Tấn công là cách phòng thủ tốt nhất”

Đúng vậy, điều này phần nào đó đúng đắn trong Android khi nói đến việc lưu trữ các API Key và bảo vệ chúng khỏi các hacker.

Bạn cần giữ các API key của mình ở chế độ riêng tư và an toàn vì nhiều lý do. Nếu 1 hacker giành được quyền truy cập vào API key của bạn họ có thể:

  • Thực hiện các request API và điều này có thể làm tăng đáng kể chi phí thanh toán
  • Sử dụng nó để làm gián đoạn dữ liệu của người dùng hiện đang sử dụng ứng dụng

Trước khi đi sâu vào việc tăng cường bảo mật cho API keys ta cùng xem cách hầu hết các nhà phát triển hiện đang lưu trữ các API key :

Cách lưu trữ API key truyền thống

  1. Lưu trữ trong source code

    savesourdcode

  2. Lưu trữ trong String resource/file

    cách này chắc chắn không an toàn và với một chút kỹ thuật đảo ngược, hacker có thể dễ dàng giải mã API key lưu trữ trong bất kỳ file xml của ứng dụng Android. Ngoài ra, có một lý do rõ ràng hơn, nếu repo của bạn là công khai thì tệp string.xml của bạn cũng sẽ như vậy. Điều đó có nghĩa là API key cũng sẽ được công khai.

    savestringresource

  3. Lưu trữ trong config gradle

    savegradle

screen shot 2021 03 26 at 09 36 48

Dường như đây là sự lựa chọn phổ biến nhất. Bạn có thể thêm vào tệp build.gradle sau đó sử dụng nó thông qua lớp BuildConfig được tạo ra. Mặc dù điều này an toàn hơn so với việc lưu trữ nó trong các tệp XML, nhưng APK keys của bạn vẫn có thể được giải mã bởi ai đó thông qua kỹ thuật đảo ngược. Do đó, đây không hẳn là cách an toàn để lưu trữ API keys

Dưới đây mình sẽ demo cho các bạn tại sao API keys lại dễ dàng bị lộ với việc decode chỉ khoảng 10 giây là có thể xem được.

Java code thì dễ dàng bị dịch ngược. Mặt khác C++ không thể bị dược ngược nhưng có thể bị disassembled (phân dịch), điều này giúp bảo mật hơn phần nào đó.

Chúng ta sẽ sử dụng lợi thế này và thực tế là Android đi kèm với NDK (Native Developer Toolkit) giúp chúng ta viết code bằng C++ và sử dụng nó bên trong ứng dụng của mình.

Thiết lập môi trường

Trong Android Studio thiết lập NDK và BuildTools với 3 công cụ chính bao gồm:

  • The Android Native Development Kit (NDK): một bộ công cụ cho phép sử dụng code C và C++ với Android, đồng thời cung cấp cá thư viện nền tảng cho phép bạn quản lý các hoặc động gốc và truy cập vào các thành phần vật lý của thiết bị, chẳng hạn như cảm biến, cảm ứng…

  • CMake: một công cụ xây dựng bên ngoài hoạt động cùng Gradle để xây dựng thư viện native. Không cần sử dụng thành phần này nếu chỉ sử dụng ndk-build

  • LLBD (Low Level Debugger): trình gỡ lỗi Android Studio sử dụng để gỡ lỗi của Native Code

    image 4  1

Cùng bắt tay vào code 1 ứng dụng đơn giản sử dụng NDK để nâng cao bảo mật.

Bước 1: Tạo file native-lib.cpp

Tạo 1 thư mục mới, cpp bên trong thư mục app/src/main

Bên trong thư mục cpp tạo 1 C/C++ Source File được đặt tên là native-lib.cpp

screen shot 2021 03 26 at 11 14 15

Bước 2: Lưu trữ API key trong file native-lib.cpp

Trong file native-lib.cpp , thêm các dòng code sau :

#include <jni.h>
#include <string>

extern "C" {

    JNIEXPORT jstring JNICALL
    Java_com_binhdrm_ndksecuritytutorial_MainActivity_invokeNativeFunction(JNIEnv *env, jobject object) {
        std::string api_key = "22310678d9a751d811f41c6c33a78db368";
        return env->NewStringUTF(api_key.c_str());
    }
}

Cùng xem kỹ hơn tên của hàm C++

Java_com_binhdrm_ndksecuritytutorial_MainActivity_invokeNativeFunction(...) được khai báo ở bên trên từ trái qua phải

_invokeNativeFunction: Đề cập trực tiếp đến phương thức mà sẽ sử dụng trong code Java sau này.

_MainActivity : Đề cập đến đối tượng Java mà bạn muốn sử dụng API key, nơi bạn sẽ tương tác với code C++ được mã hoá và nhận được tham chiếu đến API key.

_com_binhdrm_ndksecuritytutorial : tên của package chứa class MainActivity . Điều này luôn trỏ đến gói của lớp mà bạn định sử dụng nó. Vì vậy nếu package tên là com.binhdrm.ndksecuritytutorial thì sẽ trở thành com_binhdrm_ndksecuritytutorial.

API key của bạn được lưu trữ bằngapi_key trong hàm C++ và trả về hiển thị trong đoạn code ở trên

Bước 3: Tạo file CMakeLists.txt

Bên trong thư mục app/ tạo 1 file mới tên là CMakeLists.txt theo code như sau:

# Sets the minimum version of CMake required to build your native library.
# This ensures that a certain set of CMake features is available to
# your build.

cmake_minimum_required(VERSION 3.4.1)

# Specifies a library name, specifies whether the library is STATIC or
# SHARED, and provides relative paths to the source code. You can
# define multiple libraries by adding multiple add.library() commands,
# and CMake builds them for you. When you build your app, Gradle
# automatically packages shared libraries with your APK.

add_library( # Specifies the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp )

Bước 4: Thiết lập Gradle cho CMake

Thêm dòng code sau vào block android trong file build.gradle

android {
  ...
  externalNativeBuild {
    cmake {
        path "CMakeLists.txt"
    }
  }
}

Rebuild lại project sau khi thay đổi file Gradle

Bước 5: Thêm code sau vào file MainActivity.java:

static {
    System.loadLibrary("native-lib");
}

private native String invokeNativeFunction();

Với việc gọi hàm System.loadLibrary("native-lib") dùng để khởi tạo block load từ code C++, cái mà bạn đã viết trong file native-lib.cpp

Sau khi thực hiện xong việc này thì bạn có thể nhận được một tham chiếu đến phương thức của mình bằng cách khai báo một hàm Java bên ngoài cùng tên với hàm được đề cập trong Bước 2

Trong ví dụ ở đây là invokeNativeFunction

Bây giờ để lấy được thông tin API key bạn chỉ cần gọi invokeNativeFunction()

screen shot 2021 03 26 at 14 04 06

Vậy là xong một ví dụ đơn giản về việc tăng cường bảo mật bằng NDK.

Các bạn có thể tham khảo source code sample ở đây : Github

Kết luận

Mặc dù không hẳn là một cách bảo mật tuyệt đối nhưng với việc sử dụng NDK để tăng cường bảo mật thì những hacker thiếu kinh nghiệm cũng khó để lấy được thông tin của bạn hơn. Hơn nữa cũng là thêm một lớp bảo mật để bảo vệ thông tin ứng dụng của bạn.

Tham khảo:

https://www.codementor.io/blog/kotlin-apikeys-7o0g54qk5b

https://androidsecurity.info/storing-your-secure-information-in-the-ndk/


Tags

202103androidsecurityndk
binh.tran

binh.tran

Developer

Related Posts

[Hướng dẫn] Shortcuts: Ứng dụng "mạnh mẽ" nhất Apple tạo ra cho iOS
[Hướng dẫn] Shortcuts: Ứng dụng "mạnh mẽ" nhất Apple tạo ra cho iOS
March 26, 2021
2 min
System operator: Những câu chuyện chưa từng được kể (Phần 1)
Others
System operator: Những câu chuyện chưa từng được kể (Phần 1)
March 31, 2021
5 min
Why Protocol-Oriented Programming?
Articles
Why Protocol-Oriented Programming?
March 31, 2021
2 min
© 2021, All Rights Reserved.

Quick Links

HomeOur Team

Social Media