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ị. Show
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ànKhi 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ụngNế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. Kotlinval intent = Intent(Intent.ACTION_SEND) val possibleActivitiesList: List<ResolveInfo> = // 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) { Intent.createChooser(intent, title)
}
startActivity(chooser)
} else if (intent.resolveActivity(packageManager) != null) { }JavaIntent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager() // 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) { Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);
} else if (intent.resolveActivity(getPackageManager()) != null) { }Thông tin liên quan:
Áp dụng các quyền dựa trên chữ kýKhi bạn chia sẻ dữ liệu giữa hai ứng dụng mà bạn kiểm soát hoặc sở hữu, 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"
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ụngKhô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 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
5 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 của phần tử <manifest xmlns:android="http://schemas.android.com/apk/res/android"
7 là <manifest xmlns:android="http://schemas.android.com/apk/res/android"
8 trên các phiên bản Android đó.<manifest xmlns:android="http://schemas.android.com/apk/res/android" </manifest>Yêu cầu thông tin xác thực trước khi hiện thông tin nhạy cảmKhi 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ạngCá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: Kotlinval url = URL("https://www.google.com") val urlConnection = url.openConnection() as HttpsURLConnection urlConnection.connect() urlConnection.inputStream.use { }JavaURL 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ạngNế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:
<manifest ... > </manifest>
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ạnTrì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:
Để 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ý . Thông tin liên quan:
Cẩn trọng khi sử dụng các đối tượng WebViewCác đối tượng <manifest xmlns:android="http://schemas.android.com/apk/res/android" </manifest>4 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 <manifest xmlns:android="http://schemas.android.com/apk/res/android" </manifest>5 của ứng dụng tải. Ngoài ra, bạn không bao giờ được bật 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 <manifest xmlns:android="http://schemas.android.com/apk/res/android" </manifest>5 của ứng dụng. Sử dụng các kênh thư HTMLNế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: Kotlinval 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() { })
// Send a message from channel[1] to channel[0].
channel[1].postMessage(WebMessage("My secure message"))JavaIntent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager() // 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) { Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);
} else if (intent.resolveActivity(getPackageManager()) != null) { }0 Thông tin liên quan:
Cấp các quyền phù hợpChỉ 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ềnBấ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 <manifest xmlns:android="http://schemas.android.com/apk/res/android" </manifest>9 và val url = URL("https://www.google.com") val urlConnection = url.openConnection() as HttpsURLConnection urlConnection.connect() urlConnection.inputStream.use { }0: KotlinIntent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager() // 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) { Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);
} else if (intent.resolveActivity(getPackageManager()) != null) { }1 JavaIntent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager() // 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) { Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);
} else if (intent.resolveActivity(getPackageManager()) != null) { }2 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:
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:
Đ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: KotlinIntent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager() // 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) { Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);
} else if (intent.resolveActivity(getPackageManager()) != null) { }3 JavaIntent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager() // 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) { Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);
} else if (intent.resolveActivity(getPackageManager()) != null) { }4 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 val url = URL("https://www.google.com") val urlConnection = url.openConnection() as HttpsURLConnection urlConnection.connect() urlConnection.inputStream.use { }7 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 val url = URL("https://www.google.com") val urlConnection = url.openConnection() as HttpsURLConnection urlConnection.connect() urlConnection.inputStream.use { }8. Các tệp này bao gồm mọi tệp đối tượng được chia sẻ ( val url = URL("https://www.google.com") val urlConnection = url.openConnection() as HttpsURLConnection urlConnection.connect() urlConnection.inputStream.use { }
Thông tin liên quan: Lưu trữ dữ liệu một cách an toànMặ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ớ trongBộ 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á tất cả 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 để ghi dữ liệu vào bộ nhớ trong: KotlinIntent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager() // 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) { Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);
} else if (intent.resolveActivity(getPackageManager()) != null) { }5 JavaIntent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager() // 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) { Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);
} else if (intent.resolveActivity(getPackageManager()) != null) { }6 Đoạn mã sau đây cho thấy hoạt động đảo ngược, đọc dữ liệu từ bộ nhớ trong: KotlinIntent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager() // 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) { Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);
} else if (intent.resolveActivity(getPackageManager()) != null) { }7 JavaIntent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager() // 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) { Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);
} else if (intent.resolveActivity(getPackageManager()) != null) { }8 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ụngHã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 . 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ẵnNế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 để . Kiểm tra tính hợp lệ của dữ liệuNế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: KotlinIntent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager() // 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) { Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);
} else if (intent.resolveActivity(getPackageManager()) != null) { }9 Java<manifest xmlns:android="http://schemas.android.com/apk/res/android"
0Chỉ 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 URL url = new URL("https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream(); 4. Đối với các bộ nhớ đệm có dung lượng từ 1 MB trở xuống, hãy sử dụng URL url = new URL("https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream(); 5. Cả hai phương thức đều cung cấp cho bạn đối tượng URL url = new URL("https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream(); 6 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<manifest xmlns:android="http://schemas.android.com/apk/res/android"
1Java<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2Lưu ý: Nếu bạn sử dụng URL url = new URL("https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream(); 4 để đặ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 URL url = new URL("https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream(); 8 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 URL url = new URL("https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream(); 9 để tạo hoặc truy cập vào các đối tượng <manifest ... > </manifest>0 của ứng dụng, hãy sử dụng <manifest ... > </manifest>1. 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 <manifest ... > </manifest>2. Thay vào đó, hãy làm theo các bước . 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ộcHầ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 PlayLư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ụngTrướ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: |