Tăng cường tính bảo mật của ứng dụng

Việc tăng cường tính bảo mật cho ứng dụng sẽ giúp bạn duy trì sự tin tưởng của người dùng và tính toàn vẹn của thiết bị.

Trang này trình bày một số phương pháp hay nhất có tác động tích cực đáng kể đến tính bảo mật của ứng dụng.

Thực thi hoạt động giao tiếp an toàn

Khi bảo vệ dữ liệu được trao đổi giữa ứng dụng của bạn và các ứng dụng khác hoặc giữa ứng dụng của bạn và một trang web, bạn sẽ cải thiện độ ổn định của ứng dụng cũng như bảo vệ dữ liệu mà bạn gửi và nhận.

Bảo vệ hoạt động giao tiếp giữa các ứng dụng

Để giao tiếp an toàn hơn giữa các ứng dụng, hãy dùng ý định ngầm ẩn cùng trình chọn ứng dụng, quyền dựa trên chữ ký và nhà cung cấp nội dung không được xuất.

Hiển thị trình chọn ứng dụng

Nếu một ý định ngầm ẩn có thể mở ít nhất hai ứng dụng trên thiết bị của người dùng, hãy hiển thị rõ ràng trình chọn ứng dụng. Chiến lược tương tác này cho phép người dùng chuyển thông tin nhạy cảm đến một ứng dụng mà họ tin tưởng.

Kotlin

val intent = Intent(Intent.ACTION_SEND)
val possibleActivitiesList: List<ResolveInfo> =
        packageManager.queryIntentActivities(intent, PackageManager.MATCH_ALL)

// Verify that an activity in at least two apps on the user's device
// can handle the intent. Otherwise, start the intent only if an app
// on the user's device can handle the intent.
if (possibleActivitiesList.size > 1) {

    // Create intent to show chooser.
    // Title is something similar to "Share this photo with."

    val chooser = resources.getString(R.string.chooser_title).let { title ->
        Intent.createChooser(intent, title)
    }
    startActivity(chooser)
} else if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
}

Java

Intent intent = new Intent(Intent.ACTION_SEND);
List<ResolveInfo> possibleActivitiesList = getPackageManager()
        .queryIntentActivities(intent, PackageManager.MATCH_ALL);

// Verify that an activity in at least two apps on the user's device
// can handle the intent. Otherwise, start the intent only if an app
// on the user's device can handle the intent.
if (possibleActivitiesList.size() > 1) {

    // Create intent to show chooser.
    // Title is something similar to "Share this photo with."

    String title = getResources().getString(R.string.chooser_title);
    Intent chooser = Intent.createChooser(intent, title);
    startActivity(chooser);
} else if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
}

Thông tin liên quan:

Áp dụng các quyền dựa trên chữ ký

Khi chia sẻ dữ liệu giữa hai ứng dụng mà bạn sở hữu hoặc có quyền kiểm soát, hãy sử dụng các quyền dựa trên chữ ký. Các quyền này không yêu cầu người dùng xác nhận và thay vào đó, hãy kiểm tra để đảm bảo rằng các ứng dụng truy cập vào dữ liệu đã được xác nhận bằng cùng một khoá ký. Do đó, các quyền này đem đến trải nghiệm người dùng an toàn và đơn giản hơn.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <permission android:name="my_custom_permission_name"
                android:protectionLevel="signature" />

Thông tin liên quan:

Không cho phép truy cập thông tin về các nhà cung cấp nội dung của ứng dụng

Không cho phép ứng dụng của các nhà phát triển khác truy cập vào các đối tượng ContentProvider của ứng dụng một cách rõ ràng, trừ phi bạn có ý định gửi dữ liệu từ ứng dụng của mình đến một ứng dụng khác mà bạn không sở hữu. Chế độ cài đặt này rất quan trọng nếu ứng dụng của bạn có thể được cài đặt trên các thiết bị chạy Android 4.1.1 (API cấp 16) trở xuống, vì theo mặc định, thuộc tính android:exported của phần tử <provider>true trên các phiên bản Android đó.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <application ... >
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.example.myapp.fileprovider"
            ...
            android:exported="false">
            <!-- Place child elements of <provider> here. -->
        </provider>
        ...
    </application>
</manifest>

Yêu cầu thông tin xác thực trước khi hiện thông tin nhạy cảm

Khi bạn yêu cầu người dùng cung cấp thông tin xác thực để họ có thể truy cập vào thông tin nhạy cảm hoặc nội dung cao cấp trong ứng dụng, hãy yêu cầu mã PIN/mật khẩu/hình mở khoá hoặc thông tin xác thực sinh trắc học, chẳng hạn như tính năng nhận dạng khuôn mặt hoặc nhận dạng vân tay.

Để tìm hiểu thêm về cách yêu cầu thông tin xác thực sinh trắc học, hãy xem hướng dẫn về quy trình xác thực sinh trắc học.

Áp dụng các biện pháp bảo mật mạng

Các phần sau đây mô tả cách bạn có thể cải thiện tính bảo mật mạng của ứng dụng.

Sử dụng lưu lượng truy cập TLS (Bảo mật tầng truyền tải)

Nếu ứng dụng của bạn giao tiếp với một máy chủ web có chứng chỉ do một tổ chức phát hành chứng chỉ (CA) nổi tiếng và đáng tin cậy cấp, hãy sử dụng yêu cầu HTTPS như sau:

Kotlin

val url = URL("https://www.google.com")
val urlConnection = url.openConnection() as HttpsURLConnection
urlConnection.connect()
urlConnection.inputStream.use {
    ...
}

Java

URL url = new URL("https://www.google.com");
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.connect();
InputStream in = urlConnection.getInputStream();

Thêm một cấu hình bảo mật mạng

Nếu ứng dụng của bạn dùng các CA mới hoặc tuỳ chỉnh, thì bạn có thể khai báo chế độ cài đặt bảo mật mạng trong tệp cấu hình. Quá trình này cho phép bạn tạo cấu hình mà không cần sửa đổi bất kỳ mã ứng dụng nào.

Để thêm một tệp cấu hình bảo mật mạng vào ứng dụng, hãy làm theo các bước sau:

  1. Khai báo cấu hình trong tệp kê khai của ứng dụng:
  2. <manifest ... >
        <application
            android:networkSecurityConfig="@xml/network_security_config"
            ... >
            <!-- Place child elements of <application> element here. -->
        </application>
    </manifest>
  3. Thêm một tệp tài nguyên XML nằm tại res/xml/network_security_config.xml.

    Hãy chỉ định rằng tất cả lưu lượng truy cập đến các miền cụ thể đều phải sử dụng HTTPS bằng cách vô hiệu hoá dữ liệu chưa được mã hoá (clear-text):

    <network-security-config>
        <domain-config cleartextTrafficPermitted="false">
            <domain includeSubdomains="true">secure.example.com</domain>
            ...
        </domain-config>
    </network-security-config>

    Trong quá trình phát triển, bạn có thể sử dụng phần tử <debug-overrides> để cho phép rõ ràng các chứng chỉ do người dùng cài đặt. Phần tử này ghi đè các tuỳ chọn quan trọng về bảo mật của ứng dụng trong quá trình gỡ lỗi và kiểm thử mà không ảnh hưởng đến cấu hình phát hành của ứng dụng. Đoạn mã sau đây cho biết cách xác định phần tử này trong tệp XML cấu hình bảo mật mạng của ứng dụng:

    <network-security-config>
        <debug-overrides>
            <trust-anchors>
                <certificates src="user" />
            </trust-anchors>
        </debug-overrides>
    </network-security-config>

Thông tin liên quan: Cấu hình bảo mật mạng

Tạo trình quản lý tin cậy của riêng bạn

Trình kiểm tra TLS của bạn không nên chấp nhận mọi chứng chỉ. Có thể bạn sẽ phải thiết lập một trình quản lý tin cậy và xử lý mọi cảnh báo TLS xảy ra nếu trường hợp sử dụng của bạn tuân theo một trong các điều kiện sau:

  • Bạn đang kết nối với một máy chủ web có chứng chỉ do một CA mới hoặc tuỳ chỉnh ký.
  • CA đó không đáng tin cậy đối với thiết bị bạn đang dùng.
  • Bạn không thể sử dụng cấu hình bảo mật mạng.

Để tìm hiểu thêm về cách hoàn tất các bước này, hãy xem nội dung thảo luận về cách xử lý tổ chức phát hành chứng chỉ không xác định.

Thông tin liên quan:

Cẩn trọng khi sử dụng các đối tượng WebView

Các đối tượng WebView trong ứng dụng không nên cho phép người dùng chuyển đến những trang web nằm ngoài tầm kiểm soát của bạn. Bất cứ khi nào có thể, hãy dùng danh sách cho phép để hạn chế nội dung mà đối tượng WebView của ứng dụng tải.

Ngoài ra, bạn không bao giờ được bật chế độ hỗ trợ giao diện JavaScript trừ phi bạn hoàn toàn nắm quyền kiểm soát và tin tưởng nội dung trong các đối tượng WebView của ứng dụng.

Sử dụng các kênh thư HTML

Nếu ứng dụng của bạn cần sử dụng chế độ hỗ trợ giao diện JavaScript trên các thiết bị chạy Android 6.0 (API cấp 23) trở lên, hãy sử dụng các kênh thư HTML thay vì việc giao tiếp giữa một trang web và ứng dụng, như bạn có thể thấy trong đoạn mã sau:

Kotlin

val myWebView: WebView = findViewById(R.id.webview)

// channel[0] and channel[1] represent the two ports.
// They are already entangled with each other and have been started.
val channel: Array<out WebMessagePort> = myWebView.createWebMessageChannel()

// Create handler for channel[0] to receive messages.
channel[0].setWebMessageCallback(object : WebMessagePort.WebMessageCallback() {

    override fun onMessage(port: WebMessagePort, message: WebMessage) {
        Log.d(TAG, "On port $port, received this message: $message")
    }
})

// Send a message from channel[1] to channel[0].
channel[1].postMessage(WebMessage("My secure message"))

Java

WebView myWebView = (WebView) findViewById(R.id.webview);

// channel[0] and channel[1] represent the two ports.
// They are already entangled with each other and have been started.
WebMessagePort[] channel = myWebView.createWebMessageChannel();

// Create handler for channel[0] to receive messages.
channel[0].setWebMessageCallback(new WebMessagePort.WebMessageCallback() {
    @Override
    public void onMessage(WebMessagePort port, WebMessage message) {
         Log.d(TAG, "On port " + port + ", received this message: " + message);
    }
});

// Send a message from channel[1] to channel[0].
channel[1].postMessage(new WebMessage("My secure message"));

Thông tin liên quan:

Cấp các quyền phù hợp

Chỉ yêu cầu số lượng quyền tối thiểu cần thiết để ứng dụng hoạt động bình thường. Nếu được, ứng dụng của bạn nên từ bỏ một số quyền không cần dùng nữa.

Sử dụng ý định để trì hoãn các quyền

Bất cứ khi nào có thể, không nên thêm quyền vào ứng dụng của bạn để thực hiện một hành động mà ứng dụng khác có thể hoàn thành. Thay vào đó, hãy dùng ý định để trì hoãn yêu cầu này cho một ứng dụng khác đã có quyền cần thiết.

Ví dụ sau đây cho biết cách sử dụng ý định để hướng người dùng chuyển đến một ứng dụng danh bạ thay vì yêu cầu các quyền READ_CONTACTSWRITE_CONTACTS:

Kotlin

// Delegates the responsibility of creating the contact to a contacts app,
// which has already been granted the appropriate WRITE_CONTACTS permission.
Intent(Intent.ACTION_INSERT).apply {
    type = ContactsContract.Contacts.CONTENT_TYPE
}.also { intent ->
    // Make sure that the user has a contacts app installed on their device.
    intent.resolveActivity(packageManager)?.run {
        startActivity(intent)
    }
}

Java

// Delegates the responsibility of creating the contact to a contacts app,
// which has already been granted the appropriate WRITE_CONTACTS permission.
Intent insertContactIntent = new Intent(Intent.ACTION_INSERT);
insertContactIntent.setType(ContactsContract.Contacts.CONTENT_TYPE);

// Make sure that the user has a contacts app installed on their device.
if (insertContactIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(insertContactIntent);
}

Ngoài ra, nếu ứng dụng của bạn cần thực hiện thao tác I/O dựa trên tệp, chẳng hạn như truy cập vào bộ nhớ hoặc chọn tệp, thì ứng dụng không cần các quyền đặc biệt vì hệ thống có thể hoàn thành những thao tác này thay cho ứng dụng. Tốt hơn hết, sau khi người dùng chọn nội dung tại một URI cụ thể, ứng dụng thực hiện lệnh gọi sẽ được cấp quyền đối với tài nguyên đã chọn.

Thông tin liên quan:

Chia sẻ dữ liệu một cách an toàn trên nhiều ứng dụng

Hãy làm theo những phương pháp hay nhất dưới đây để chia sẻ nội dung ứng dụng của bạn với các ứng dụng khác theo cách an toàn hơn:

  • Thực thi quyền chỉ đọc hoặc quyền chỉ ghi khi cần.
  • Cung cấp cho khách hàng quyền truy cập một lần vào dữ liệu bằng cách sử dụng cờ FLAG_GRANT_READ_URI_PERMISSIONFLAG_GRANT_WRITE_URI_PERMISSION.
  • Khi chia sẻ dữ liệu, hãy dùng các URI content://, không phải URI file://. Các thực thể của FileProvider sẽ giúp bạn thực hiện việc này.

Đoạn mã sau đây cho biết cách sử dụng cờ cấp quyền URI và quyền của nhà cung cấp nội dung để hiển thị tệp PDF của ứng dụng trong một ứng dụng trình xem PDF riêng:

Kotlin

// Create an Intent to launch a PDF viewer for a file owned by this app.
Intent(Intent.ACTION_VIEW).apply {
    data = Uri.parse("content://com.example/personal-info.pdf")

    // This flag gives the started app read access to the file.
    addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}.also { intent ->
    // Make sure that the user has a PDF viewer app installed on their device.
    intent.resolveActivity(packageManager)?.run {
        startActivity(intent)
    }
}

Java

// Create an Intent to launch a PDF viewer for a file owned by this app.
Intent viewPdfIntent = new Intent(Intent.ACTION_VIEW);
viewPdfIntent.setData(Uri.parse("content://com.example/personal-info.pdf"));

// This flag gives the started app read access to the file.
viewPdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

// Make sure that the user has a PDF viewer app installed on their device.
if (viewPdfIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(viewPdfIntent);
}

Lưu ý: Việc thực thi các tệp trong thư mục gốc có thể ghi của ứng dụng bị coi là một lỗi vi phạm W^X. Vì lý do này, các ứng dụng không đáng tin cậy nhắm đến Android 10 (API cấp 29) trở lên không thể gọi exec() trên các tệp trong thư mục gốc của ứng dụng. Chỉ mã nhị phân được nhúng trong tệp APK của ứng dụng mới có thể làm như vậy. Ngoài ra, các ứng dụng nhắm đến Android 10 trở lên không thể sửa đổi mã có thể thực thi trong bộ nhớ từ các tệp đã mở bằng dlopen(). Các tệp này bao gồm mọi tệp đối tượng được chia sẻ (.so) có hình thức chuyển vị trí văn bản.

Thông tin liên quan: android:grantUriPermissions

Lưu trữ dữ liệu một cách an toàn

Mặc dù ứng dụng của bạn có thể yêu cầu quyền truy cập vào thông tin nhạy cảm của người dùng, nhưng người dùng sẽ chỉ cấp cho ứng dụng quyền truy cập vào dữ liệu nếu họ tin rằng bạn có biện pháp bảo vệ đúng cách.

Lưu trữ dữ liệu riêng tư vào bộ nhớ trong

Bộ nhớ trong của thiết bị được đặt trong hộp cát cho mỗi ứng dụng sẽ lưu trữ tất cả dữ liệu riêng tư của người dùng. Ứng dụng của bạn không cần yêu cầu quyền xem các tệp này và các ứng dụng khác cũng không thể truy cập vào tệp. Khi người dùng gỡ cài đặt một ứng dụng, thiết bị sẽ xoá mọi tệp mà ứng dụng đó đã lưu vào bộ nhớ trong như một biện pháp bảo mật bổ sung.

Đoạn mã sau đây minh hoạ một cách dùng để ghi dữ liệu vào bộ nhớ trong:

Kotlin

// Creates a file with this name, or replaces an existing file
// that has the same name. Note that the file name cannot contain
// path separators.
val FILE_NAME = "sensitive_info.txt"
val fileContents = "This is some top-secret information!"
File(filesDir, FILE_NAME).bufferedWriter().use { writer ->
    writer.write(fileContents)
}

Java

// Creates a file with this name, or replaces an existing file
// that has the same name. Note that the file name cannot contain
// path separators.
final String FILE_NAME = "sensitive_info.txt";
String fileContents = "This is some top-secret information!";
try (BufferedWriter writer =
             new BufferedWriter(new FileWriter(new File(getFilesDir(), FILE_NAME)))) {
    writer.write(fileContents);
} catch (IOException e) {
    // Handle exception.
}

Đoạn mã sau đây minh hoạ thao tác đảo ngược, giúp đọc dữ liệu của bộ nhớ trong:

Kotlin

val FILE_NAME = "sensitive_info.txt"
val contents = File(filesDir, FILE_NAME).bufferedReader().useLines { lines ->
    lines.fold("") { working, line ->
        "$working\n$line"
    }
}

Java

final String FILE_NAME = "sensitive_info.txt";
StringBuffer stringBuffer = new StringBuffer();
try (BufferedReader reader =
             new BufferedReader(new FileReader(new File(getFilesDir(), FILE_NAME)))) {

    String line = reader.readLine();
    while (line != null) {
        stringBuffer.append(line).append('\n');
        line = reader.readLine();
    }
} catch (IOException e) {
    // Handle exception.
}

Thông tin liên quan:

Lưu trữ dữ liệu trong bộ nhớ ngoài dựa trên trường hợp sử dụng

Hãy sử dụng bộ nhớ ngoài đối với những tệp có kích thước lớn, không chứa thông tin nhạy cảm, dành riêng cho ứng dụng của bạn cũng như những tệp mà ứng dụng của bạn chia sẻ với các ứng dụng khác. Các API cụ thể mà bạn dùng phụ thuộc vào việc ứng dụng của bạn được thiết kế để truy cập vào các tệp dành riêng cho ứng dụng hay truy cập vào các tệp được chia sẻ.

Nếu một tệp không chứa thông tin riêng tư hoặc nhạy cảm mà chỉ cung cấp giá trị cho người dùng trong ứng dụng, hãy lưu trữ tệp đó trong một thư mục dành riêng cho ứng dụng trên bộ nhớ ngoài.

Nếu ứng dụng của bạn cần truy cập hoặc lưu trữ một tệp cung cấp giá trị cho các ứng dụng khác, hãy sử dụng một trong những API sau đây tuỳ theo trường hợp sử dụng của bạn:

Kiểm tra dung lượng lưu trữ có sẵn

Nếu ứng dụng của bạn tương tác với thiết bị lưu trữ bên ngoài có thể tháo rời, hãy lưu ý rằng người dùng có thể tháo thiết bị lưu trữ khi ứng dụng đang cố gắng truy cập. Bao gồm logic để xác minh rằng thiết bị lưu trữ hiện có sẵn.

Kiểm tra tính hợp lệ của dữ liệu

Nếu ứng dụng của bạn sử dụng dữ liệu trong bộ nhớ ngoài, hãy đảm bảo rằng nội dung của dữ liệu không bị hỏng hoặc bị sửa đổi. Bao gồm logic để xử lý các tệp không còn ở định dạng ổn định.

Đoạn mã sau đây cho thấy ví dụ về trình xác minh hàm băm:

Kotlin

val hash = calculateHash(stream)
// Store "expectedHash" in a secure location.
if (hash == expectedHash) {
    // Work with the content.
}

// Calculating the hash code can take quite a bit of time, so it shouldn't
// be done on the main thread.
suspend fun calculateHash(stream: InputStream): String {
    return withContext(Dispatchers.IO) {
        val digest = MessageDigest.getInstance("SHA-512")
        val digestStream = DigestInputStream(stream, digest)
        while (digestStream.read() != -1) {
            // The DigestInputStream does the work; nothing for us to do.
        }
        digest.digest().joinToString(":") { "%02x".format(it) }
    }
}

Java

Executor threadPoolExecutor = Executors.newFixedThreadPool(4);
private interface HashCallback {
    void onHashCalculated(@Nullable String hash);
}

boolean hashRunning = calculateHash(inputStream, threadPoolExecutor, hash -> {
    if (Objects.equals(hash, expectedHash)) {
        // Work with the content.
    }
});

if (!hashRunning) {
    // There was an error setting up the hash function.
}

private boolean calculateHash(@NonNull InputStream stream,
                              @NonNull Executor executor,
                              @NonNull HashCallback hashCallback) {
    final MessageDigest digest;
    try {
        digest = MessageDigest.getInstance("SHA-512");
    } catch (NoSuchAlgorithmException nsa) {
        return false;
    }

    // Calculating the hash code can take quite a bit of time, so it shouldn't
    // be done on the main thread.
    executor.execute(() -> {
        String hash;
        try (DigestInputStream digestStream =
                new DigestInputStream(stream, digest)) {
            while (digestStream.read() != -1) {
                // The DigestInputStream does the work; nothing for us to do.
            }
            StringBuilder builder = new StringBuilder();
            for (byte aByte : digest.digest()) {
                builder.append(String.format("%02x", aByte)).append(':');
            }
            hash = builder.substring(0, builder.length() - 1);
        } catch (IOException e) {
            hash = null;
        }

        final String calculatedHash = hash;
        runOnUiThread(() -> hashCallback.onHashCalculated(calculatedHash));
    });
    return true;
}

Chỉ lưu trữ dữ liệu không nhạy cảm trong các tệp bộ nhớ đệm

Để truy cập nhanh hơn vào dữ liệu không nhạy cảm của ứng dụng, hãy lưu dữ liệu đó trong bộ nhớ đệm của thiết bị. Đối với các bộ nhớ đệm có dung lượng từ 1 MB trở lên, hãy sử dụng getExternalCacheDir(). Đối với các bộ nhớ đệm có dung lượng từ 1 MB trở xuống, hãy sử dụng getCacheDir(). Cả hai phương thức đều cung cấp cho bạn đối tượng File có chứa dữ liệu đã lưu vào bộ nhớ đệm của ứng dụng.

Đoạn mã sau đây cho biết cách lưu tệp vào bộ nhớ đệm mà ứng dụng của bạn đã tải xuống gần đây:

Kotlin

val cacheFile = File(myDownloadedFileUri).let { fileToCache ->
    File(cacheDir.path, fileToCache.name)
}

Java

File cacheDir = getCacheDir();
File fileToCache = new File(myDownloadedFileUri);
String fileToCacheName = fileToCache.getName();
File cacheFile = new File(cacheDir.getPath(), fileToCacheName);

Lưu ý: Nếu bạn sử dụng getExternalCacheDir() để đặt bộ nhớ đệm của ứng dụng trong bộ nhớ dùng chung, thì người dùng có thể tháo phương tiện chứa bộ nhớ này trong khi ứng dụng của bạn đang chạy. Bao gồm logic để xử lý linh hoạt tình trạng thiếu bộ nhớ đệm xảy ra khi người dùng thực hiện hành vi trên.

Chú ý: Không có chế độ bảo mật nào áp dụng cho các tệp này. Do đó, mọi ứng dụng nhắm đến Android 10 (API cấp 29) trở xuống và có quyền WRITE_EXTERNAL_STORAGE có thể truy cập vào nội dung của bộ nhớ đệm này.

Thông tin liên quan: Tổng quan về lưu trữ dữ liệu và tệp

Sử dụng SharedPreferences ở chế độ riêng tư

Khi sử dụng getSharedPreferences() để tạo hoặc truy cập vào các đối tượng SharedPreferences của ứng dụng, hãy sử dụng MODE_PRIVATE. Bằng cách đó, chỉ có ứng dụng của bạn có thể truy cập thông tin trong tệp về lựa chọn chia sẻ ưu tiên.

Nếu bạn muốn chia sẻ dữ liệu trên nhiều ứng dụng thì đừng sử dụng đối tượng SharedPreferences. Thay vào đó, hãy làm theo các bước chia sẻ dữ liệu trên nhiều ứng dụng một cách an toàn.

Thư viện bảo mật cũng cung cấp lớp EncryptedSharedPreferences giúp bao bọc lớp SharedPreferences cũng như tự động mã hoá các khoá và giá trị.

Thông tin liên quan:

Luôn cập nhật các dịch vụ và phần phụ thuộc

Hầu hết ứng dụng đều sử dụng thư viện bên ngoài và thông tin hệ thống của thiết bị để hoàn thành các nhiệm vụ chuyên biệt. Bằng cách cập nhật các phần phụ thuộc của ứng dụng, bạn sẽ khiến các điểm giao tiếp này trở nên an toàn hơn.

Kiểm tra nhà cung cấp dịch vụ bảo mật của Dịch vụ Google Play

Lưu ý: Phần này chỉ áp dụng cho những ứng dụng nhắm đến các thiết bị đã cài đặt Dịch vụ Google Play.

Nếu ứng dụng của bạn sử dụng Dịch vụ Google Play, hãy đảm bảo dịch vụ được cập nhật trên thiết bị cài đặt ứng dụng. Thực hiện quy trình kiểm tra không đồng bộ bên ngoài luồng giao diện người dùng. Nếu thiết bị chưa được cập nhật, hãy kích hoạt lỗi uỷ quyền.

Để xác định xem Dịch vụ Google Play đã được cập nhật trên thiết bị cài đặt ứng dụng của bạn hay chưa, hãy làm theo các bước trong hướng dẫn Cập nhật trình cung cấp dịch vụ bảo mật để chống khai thác SSL.

Thông tin liên quan:

Cập nhật tất cả phần phụ thuộc ứng dụng

Trước khi triển khai ứng dụng, hãy đảm bảo rằng bạn đã cập nhật tất cả các thư viện, SDK và các phần phụ thuộc khác:

  • Đối với các phần phụ thuộc bên thứ nhất (chẳng hạn như SDK Android), hãy sử dụng các công cụ cập nhật trong Android Studio, chẳng hạn như Trình quản lý SDK.
  • Đối với các phần phụ thuộc bên thứ ba, hãy kiểm tra trang web của các thư viện mà ứng dụng của bạn sử dụng, đồng thời cài đặt mọi bản cập nhật và bản vá bảo mật có sẵn.

Thông tin liên quan: Thêm phần phụ thuộc của bản dựng

Thông tin khác

Để tìm hiểu thêm về cách tăng cường bảo mật cho ứng dụng của bạn, hãy xem các tài nguyên sau: