Bảo mật

Các tính năng trong hướng dẫn này mô tả các tính năng quản lý bảo mật mà bạn có thể triển khai trong ứng dụng trình kiểm soát chính sách thiết bị (DPC). Tài liệu này chứa mã mẫu và bạn cũng có thể sử dụng ứng dụng Test DPC làm nguồn mã mẫu cho các tính năng của Android dành cho doanh nghiệp.

Ứng dụng DPC có thể chạy ở chế độ chủ sở hữu hồ sơ trên thiết bị cá nhân hoặc ở chế độ chủ sở hữu thiết bị trên các thiết bị được quản lý toàn bộ. Bảng này cho biết những tính năng hoạt động khi DPC chạy ở chế độ chủ sở hữu hồ sơ hoặc chế độ chủ sở hữu thiết bị:

Tính năng Chủ sở hữu hồ sơ Chủ sở hữu thiết bị
Tắt quyền truy cập vào ứng dụng
Chặn ứng dụng không rõ nguồn gốc
Hạn chế tài khoản trong Google Play
Bật tính năng bảo vệ khi đặt lại về trạng thái ban đầu cho doanh nghiệp
Giám sát nhật ký quy trình của doanh nghiệp và báo cáo lỗi từ xa
Cấp quyền truy cập và xoá quyền truy cập vào chứng chỉ ứng dụng
Đặt lại mật mã an toàn
Thách thức bảo mật hồ sơ công việc

Vô hiệu hoá quyền truy cập vào ứng dụng

Đối với các tổ chức muốn chặn nhân viên chơi trò chơi hoặc xem YouTube trên thiết bị chạy Android vào một số thời điểm nhất định trong ngày hoặc một số ngày nhất định trong tuần, DPC có thể tạm thời vô hiệu hóa quyền truy cập vào ứng dụng.

Để vô hiệu hoá quyền truy cập vào các ứng dụng, DPC chạy ở chế độ chủ sở hữu thiết bị hoặc chủ sở hữu hồ sơ sẽ định cấu hình setPackagesSuspended(), sau đó ứng dụng được chọn hoạt động như thể bị tắt (trình chạy của Google sẽ chuyển ứng dụng sang màu xám). Khi nhấn vào ứng dụng đó, người dùng sẽ thấy hộp thoại hệ thống cho biết ứng dụng đó đã bị tạm ngưng.

Khi bị tạm ngưng, một ứng dụng không thể bắt đầu các hoạt động và thông báo về gói sẽ bị chặn. Các gói bị tạm ngưng không xuất hiện trên màn hình tổng quan, không thể hiển thị hộp thoại (bao gồm cả thông báo ngắn và thanh thông báo nhanh), cũng như không thể phát âm thanh hoặc rung thiết bị.

Trình chạy có thể biết được liệu một ứng dụng có bị tạm ngưng hay không bằng cách gọi phương thức isPackageSuspended(). Để biết thông tin chi tiết về cách định cấu hình tính năng tạm ngưng ứng dụng, hãy xem setPackagesSuspended.

Chặn ứng dụng không rõ nguồn gốc

Các ứng dụng không cài đặt qua Google Play (hoặc các cửa hàng ứng dụng đáng tin cậy khác) được gọi là ứng dụng không rõ nguồn gốc. Thiết bị và dữ liệu có thể gặp rủi ro cao hơn khi mọi người cài đặt các ứng dụng này.

Để ngăn ai đó cài đặt ứng dụng không rõ nguồn gốc, các thành phần quản trị của thiết bị được quản lý hoàn toàn và hồ sơ công việc có thể thêm quy tắc hạn chế người dùng DISALLOW_INSTALL_UNKNOWN_SOURCES.

Hạn chế trên toàn thiết bị của hồ sơ công việc

Khi quản trị viên của hồ sơ công việc thêm DISALLOW_INSTALL_UNKNOWN_SOURCES, quy định hạn chế chỉ áp dụng cho hồ sơ công việc. Tuy nhiên, quản trị viên của hồ sơ công việc có thể đặt hạn chế trên toàn thiết bị bằng cách đặt một cấu hình được quản lý cho Google Play. Hạn chế trên toàn thiết bị có trong Android 8.0 trở lên khi ứng dụng Google Play đã cài đặt là phiên bản 80812500 trở lên.

Để hạn chế cài đặt ứng dụng trong phạm vi Google Play, hãy làm theo các bước sau:

  1. Đặt gói cấu hình được quản lý cho gói Google Play com.android.vending.
  2. Trong gói này, hãy đặt một giá trị boolean cho khoá verify_apps:device_wide_unknown_source_block.
  3. Thêm giới hạn đối với người dùng ENSURE_VERIFY_APPS.

Ví dụ sau cho thấy cách bạn có thể kiểm tra để đảm bảo rằng Google Play có hỗ trợ chế độ cài đặt này và đặt giá trị thành true:

Kotlin

internal val DEVICE_WIDE_UNKNOWN_SOURCES = "verify_apps:device_wide_unknown_source_block"
internal val GOOGLE_PLAY_APK = "com.android.vending"

// ...

// Add the setting to Google Play's existing managed config. Supported in
// Google Play version 80812500 or higher--older versions ignore unsupported
// settings.
val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
var existingConfig = dpm.getApplicationRestrictions(adminName, GOOGLE_PLAY_APK)
val newConfig = Bundle(existingConfig)
newConfig.putBoolean(DEVICE_WIDE_UNKNOWN_SOURCES, true)
dpm.setApplicationRestrictions(adminName, GOOGLE_PLAY_APK, newConfig)

// Make sure that Google Play Protect verifies apps.
dpm.addUserRestriction(adminName, UserManager.ENSURE_VERIFY_APPS)
dpm.addUserRestriction(adminName, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)

Java

static final String DEVICE_WIDE_UNKNOWN_SOURCES =
    "verify_apps:device_wide_unknown_source_block";
static final String GOOGLE_PLAY_APK = "com.android.vending";

// ...


// Add the setting to Google Play's existing managed config. Supported in
// Google Play version 80812500 or higher--older versions ignore unsupported
// settings.
DevicePolicyManager dpm =
    (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
Bundle existingConfig =
    dpm.getApplicationRestrictions(adminName, GOOGLE_PLAY_APK);
Bundle newConfig = new Bundle(existingConfig);
newConfig.putBoolean(DEVICE_WIDE_UNKNOWN_SOURCES, true);
dpm.setApplicationRestrictions(adminName, GOOGLE_PLAY_APK, newConfig);

// Make sure that Google Play Protect verifies apps.
dpm.addUserRestriction(adminName, UserManager.ENSURE_VERIFY_APPS);
dpm.addUserRestriction(adminName, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);

Giao diện người dùng trong phần cài đặt hệ thống vẫn hoạt động nhưng hệ thống sẽ chặn việc cài đặt ứng dụng. Quy định hạn chế này ảnh hưởng đến các lượt cài đặt sau này – các ứng dụng đã cài đặt trước đây vẫn tồn tại trên thiết bị. Người dùng thiết bị có thể tiếp tục cài đặt ứng dụng vào hồ sơ cá nhân bằng Cầu gỡ lỗi Android (adb).

Để tìm hiểu thêm về các nguồn không xác định, hãy đọc bài viết Tuỳ chọn phân phối thay thế.

Hạn chế tài khoản trên Google Play

Đôi khi, một tổ chức có thể muốn cho phép mọi người thêm Tài khoản Google cá nhân (chẳng hạn như để đọc thư trong Gmail) nhưng không muốn tài khoản cá nhân đó cài đặt các ứng dụng. DPC của bạn có thể đặt một danh sách các tài khoản mà mọi người có thể sử dụng trong Google Play.

Các thành phần quản trị của thiết bị được quản lý đầy đủ hoặc hồ sơ công việc có thể hạn chế các tài khoản bằng cách đặt một cấu hình được quản lý cho Google Play. Hạn chế tài khoản sẽ áp dụng khi ứng dụng Google Play đã cài đặt là phiên bản 80970100 trở lên.

Để giới hạn các tài khoản trong Google Play, hãy làm như sau:

  1. Đặt gói cấu hình được quản lý cho gói Google Play com.android.vending.
  2. Trong gói này, hãy đặt các địa chỉ email được phân tách bằng dấu phẩy làm giá trị chuỗi cho khoá allowed_accounts.

Ví dụ sau đây cho thấy cách bạn có thể giới hạn tài khoản:

Kotlin

internal val ALLOWED_ACCOUNTS = "allowed_accounts"
internal val GOOGLE_PLAY_APK = "com.android.vending"

// ...

// Limit Google Play to one work and one personal account. Use
// a comma-separated list of account email addresses (usernames).
val googleAccounts = "ali@gmail.com,ali.connors@example.com"

// Supported in Google Play version 80970100 or higher.
val existingConfig = dpm.getApplicationRestrictions(adminName, GOOGLE_PLAY_APK)
val newConfig = Bundle(existingConfig)
newConfig.putString(ALLOWED_ACCOUNTS, googleAccounts)
dpm.setApplicationRestrictions(adminName, GOOGLE_PLAY_APK, newConfig)

Java

static final String ALLOWED_ACCOUNTS = "allowed_accounts";
static final String GOOGLE_PLAY_APK = "com.android.vending";

// ...


// Limit Google Play to one work and one personal account. Use
// a comma-separated list of account email addresses (usernames).
String googleAccounts = "ali@gmail.com,ali.connors@example.com";

// Supported in Google Play version 80970100 or higher.
Bundle existingConfig =
    dpm.getApplicationRestrictions(adminName, GOOGLE_PLAY_APK);
Bundle newConfig = new Bundle(existingConfig);
newConfig.putString(ALLOWED_ACCOUNTS, googleAccounts);
dpm.setApplicationRestrictions(adminName, GOOGLE_PLAY_APK, newConfig);

Để giới hạn Google Play chỉ ở tài khoản công việc, hãy đặt allowed_accounts thành một tài khoản được quản lý ngay khi DPC biết địa chỉ email của tài khoản. Chuỗi trống ngăn mọi người sử dụng bất kỳ tài khoản nào trong Google Play.

Bật tính năng bảo vệ khi đặt lại về trạng thái ban đầu cho doanh nghiệp

Bằng cách sử dụng tính năng bảo vệ đặt lại về trạng thái ban đầu của doanh nghiệp, các tổ chức có thể chỉ định Tài khoản Google nào có thể cấp phép cho một thiết bị đã được đặt lại về trạng thái ban đầu.

Tính năng bảo vệ đặt lại về trạng thái ban đầu cho người tiêu dùng được thiết kế để ngăn chặn hành vi đánh cắp thiết bị. Trước khi cho phép người khác cấp phép cho thiết bị sau khi đặt lại trái phép về trạng thái ban đầu (chẳng hạn như sử dụng EMM), trình hướng dẫn thiết lập yêu cầu người dùng xác thực với mọi Tài khoản Google trước đó nằm trong hồ sơ cá nhân của thiết bị.

Trong môi trường doanh nghiệp, đặt lại về trạng thái ban đầu là một công cụ quan trọng để quản lý các thiết bị của nhân viên khi một nhân viên rời khỏi tổ chức. Tuy nhiên, nếu tổ chức không biết thông tin đăng nhập tài khoản của nhân viên, thì biện pháp bảo vệ đặt lại về trạng thái ban đầu có thể chặn khả năng tổ chức cấp thiết bị cho một nhân viên khác.

Kiểm soát việc cấp phép sau khi đặt lại về trạng thái ban đầu

Khi chạy ở chế độ chủ sở hữu thiết bị, DPC của bạn có thể sử dụng setFactoryResetProtectionPolicy() để kiểm soát những tài khoản được phép cấp phép một thiết bị sau khi đặt lại về trạng thái ban đầu. Nếu bạn đặt cấu hình này thành null hoặc đặt thành danh sách trống, thì các tài khoản được phép cấp phép cho thiết bị sau khi đặt lại về trạng thái ban đầu sẽ là tài khoản trong hồ sơ cá nhân của thiết bị đó.

DPC có thể định cấu hình các tài khoản này trong suốt vòng đời của một thiết bị được quản lý hoàn toàn.

  1. Quản trị viên CNTT có thể sử dụng phương thức people.get từ People API (API Mọi người) với giá trị đặc biệt me. Thao tác này sẽ truy xuất userId cho tài khoản đã đăng nhập. userID được trả về trong khoá resourceName ở dạng people/[userId] dưới dạng một chuỗi số nguyên. Các tài khoản mới tạo có thể sẽ không dùng được cho mục đích đặt lại về trạng thái ban đầu trong 72 giờ.
  2. Bạn cũng nên cho phép một hoặc nhiều quản trị viên CNTT mở khoá thiết bị sau khi đặt lại về trạng thái ban đầu. Yêu cầu mỗi quản trị viên CNTT trong số này đăng nhập vào Tài khoản Google của họ, đồng thời làm theo bước 1 và chia sẻ userId của họ với bạn để bạn có thể thêm những userIds này vào Danh sách ở bước tiếp theo.
  3. DPC sẽ đặt một quy tắc hạn chế thích hợp cho ứng dụng bằng cách sử dụng setFactoryResetProtectionPolicy() để đặt Danh sách userId có thể cấp phép cho thiết bị đặt lại về trạng thái ban đầu.
  4. DPC cho phép các tài khoản có thể cấp phép cho các thiết bị sau khi đặt lại về trạng thái ban đầu bằng cách gửi thông báo truyền tin com.google.android.gms.auth.FRP_CONFIG_CHANGED dưới dạng một ý định tường minh để ngăn sự cố bị loại bỏ do các hạn chế ở chế độ nền.

Kotlin

const val ACTION_FRP_CONFIG_CHANGED =
    "com.google.android.gms.auth.FRP_CONFIG_CHANGED"
const val GMSCORE_PACKAGE = "com.google.android.gms"

// ...

// List of userId that can provision a factory reset device.
// You can use the value returned calling people/me endpoint.
val accountIds = listOf("000000000000000000000")

dpm.setFactoryResetProtectionPolicy(
    adminName,
    FactoryResetProtectionPolicy.Builder()
        .setFactoryResetProtectionAccounts(accountIds)
        .setFactoryResetProtectionEnabled(true)
        .build()
)

val frpChangedIntent = Intent(ACTION_FRP_CONFIG_CHANGED)

frpChangedIntent.setPackage(GMSCORE_PACKAGE)
context.sendBroadcast(frpChangedIntent)

Java

static final String ACTION_FRP_CONFIG_CHANGED =
    "com.google.android.gms.auth.FRP_CONFIG_CHANGED";
static final String GMSCORE_PACKAGE = "com.google.android.gms";

// ...

// List of userId that can provision a factory reset device.
// You can use the value returned calling people/me endpoint.
List<String> accountIds = new ArrayList<String>();
accountIds.add("000000000000000000000");

dpm.setFactoryResetProtectionPolicy(
    adminName,
    new FactoryResetProtectionPolicy.Builder()
        .setFactoryResetProtectionAccounts(accountIds)
        .setFactoryResetProtectionEnabled(true)
        .build());

Intent frpChangedIntent = new Intent(ACTION_FRP_CONFIG_CHANGED);

frpChangedIntent.setPackage(GMSCORE_PACKAGE);
context.sendBroadcast(frpChangedIntent);

Đối với các thiết bị không thể sử dụng setFactoryResetProtectionPolicy(), được giới thiệu với API cấp 30, DPC của bạn có thể sử dụng setApplicationRestrictions để thêm các tài khoản đã chọn vào cấu hình được quản lý factoryResetProtectionAdmin cho gói com.google.android.gms.

Kotlin

const val GOOGLE_PLAY_APK = "com.android.vending"
const val FACTORY_RESET_PROTECTION_ADMIN = "factoryResetProtectionAdmin"
const val DISABLE_FACTORY_RESET_PROTECTION_ADMIN = "disableFactoryResetProtectionAdmin"
const val GMSCORE_PACKAGE = "com.google.android.gms"

// ...

val existingConfig = dpm.getApplicationRestrictions(adminName, GOOGLE_PLAY_APK)
val newConfig = Bundle(existingConfig)
newConfig.putBoolean(DISABLE_FACTORY_RESET_PROTECTION_ADMIN, false)
newConfig.putString(FACTORY_RESET_PROTECTION_ADMIN, googleAccounts)
dpm.setApplicationRestrictions(adminName, GOOGLE_PLAY_APK, newConfig)

val frpChangedIntent = Intent(ACTION_FRP_CONFIG_CHANGED)

frpChangedIntent.setPackage(GMSCORE_PACKAGE)
context.sendBroadcast(frpChangedIntent)

Java

static final String GOOGLE_PLAY_APK = "com.android.vending";
static final String FACTORY_RESET_PROTECTION_ADMIN = "factoryResetProtectionAdmin";
static final String DISABLE_FACTORY_RESET_PROTECTION_ADMIN = "disableFactoryResetProtectionAdmin";
static final String GMSCORE_PACKAGE = "com.google.android.gms";

// ...

Bundle existingConfig =
        dpm.getApplicationRestrictions(adminName, GOOGLE_PLAY_APK);
Bundle newConfig = new Bundle(existingConfig);
newConfig.putBoolean(DISABLE_FACTORY_RESET_PROTECTION_ADMIN, false);
newConfig.putStringArray(FACTORY_RESET_PROTECTION_ADMIN,
        accountIds.toArray(new String[accountIds.size()]));
dpm.setApplicationRestrictions(adminName, GOOGLE_PLAY_APK, newConfig);

Intent frpChangedIntent = new Intent(ACTION_FRP_CONFIG_CHANGED);

frpChangedIntent.setPackage(GMSCORE_PACKAGE);
context.sendBroadcast(frpChangedIntent);

Tắt tính năng bảo vệ đặt lại về trạng thái ban đầu cho doanh nghiệp

Để tắt tính năng bảo vệ đặt lại về trạng thái ban đầu, DPC của bạn có thể sử dụng phương thức setFactoryResetProtectionPolicy() truyền giá trị null.

Kotlin

const val ACTION_FRP_CONFIG_CHANGED =
    "com.google.android.gms.auth.FRP_CONFIG_CHANGED"
const val GMSCORE_PACKAGE = "com.google.android.gms"

// ...

dpm.setFactoryResetProtectionPolicy(adminName, null)

val frpChangedIntent = Intent(ACTION_FRP_CONFIG_CHANGED)

frpChangedIntent.setPackage(GMSCORE_PACKAGE)
context.sendBroadcast(frpChangedIntent)

Java

static final String ACTION_FRP_CONFIG_CHANGED =
    "com.google.android.gms.auth.FRP_CONFIG_CHANGED";
static final String GMSCORE_PACKAGE = "com.google.android.gms";

// ...

dpm.setFactoryResetProtectionPolicy(adminName, null);

Intent frpChangedIntent = new Intent(ACTION_FRP_CONFIG_CHANGED);

frpChangedIntent.setPackage(GMSCORE_PACKAGE);
context.sendBroadcast(frpChangedIntent);

Đối với các thiết bị không thể sử dụng setFactoryResetProtectionPolicy(), được giới thiệu với API cấp 30, DPC của bạn có thể sử dụng setApplicationRestrictions để đặt giá trị khoá của true trong cấu hình được quản lý của disableFactoryResetProtectionAdmin cho gói com.google.android.gms.

Kotlin

const val GOOGLE_PLAY_APK = "com.android.vending"
const val FACTORY_RESET_PROTECTION_ADMIN = "factoryResetProtectionAdmin"
const val DISABLE_FACTORY_RESET_PROTECTION_ADMIN = "disableFactoryResetProtectionAdmin"
const val GMSCORE_PACKAGE = "com.google.android.gms"

// ...

val existingConfig = dpm.getApplicationRestrictions(adminName, GOOGLE_PLAY_APK)
val newConfig = Bundle(existingConfig)
newConfig.putBoolean(DISABLE_FACTORY_RESET_PROTECTION_ADMIN, true)

dpm.setApplicationRestrictions(
    adminName, GOOGLE_PLAY_SERVICES_PACKAGE, restrictions
)

val frpChangedIntent = Intent(ACTION_FRP_CONFIG_CHANGED)

frpChangedIntent.setPackage(GMSCORE_PACKAGE)
context.sendBroadcast(frpChangedIntent)

Java

static final String GOOGLE_PLAY_APK = "com.android.vending";
static final String FACTORY_RESET_PROTECTION_ADMIN = "factoryResetProtectionAdmin";
static final String DISABLE_FACTORY_RESET_PROTECTION_ADMIN = "disableFactoryResetProtectionAdmin";
static final String GMSCORE_PACKAGE = "com.google.android.gms";

// ...

Bundle existingConfig =
        dpm.getApplicationRestrictions(adminName, GOOGLE_PLAY_APK);
Bundle newConfig = new Bundle(existingConfig);
newConfig.putBoolean(DISABLE_FACTORY_RESET_PROTECTION_ADMIN, true);

dpm.setApplicationRestrictions(
    adminName, GOOGLE_PLAY_SERVICES_PACKAGE, restrictions);

Intent frpChangedIntent = new Intent(ACTION_FRP_CONFIG_CHANGED);

frpChangedIntent.setPackage(GMSCORE_PACKAGE);
context.sendBroadcast(frpChangedIntent);

Giám sát nhật ký quy trình của doanh nghiệp và báo cáo lỗi từ xa

Trong bảng điều khiển EMM, quản trị viên có thể giám sát các thiết bị được quản lý hoàn toàn bằng cách sử dụng nhật ký quy trình doanh nghiệp và báo cáo lỗi từ xa.

Ghi nhật ký hoạt động trên thiết bị của doanh nghiệp

DPC chạy ở chế độ chủ sở hữu thiết bị có thể xác định hoạt động đáng ngờ bằng cách theo dõi từ xa hoạt động trên thiết bị, bao gồm các lượt khởi chạy ứng dụng, hoạt động của Cầu gỡ lỗi Android (adb) và lượt mở khoá màn hình. Nhật ký quy trình không yêu cầu sự đồng ý của người dùng.

Để bật hoặc tắt tính năng ghi nhật ký, DPC sẽ gọi setSecurityLoggingEnabled().

Khi có một lô nhật ký mới, DeviceAdminReceiver sẽ nhận được lệnh gọi lại onSecurityLogsAvailable(). Để truy xuất nhật ký (sau khi nhận được lệnh gọi lại), DPC sẽ gọi retrieveSecurityLogs().

DPC cũng có thể gọi retrievePreRebootSecurityLogs() để tìm nạp nhật ký bảo mật được tạo trong chu kỳ khởi động lại trước đó. Đây là khoảng thời gian giữa lần khởi động lại thiết bị gần đây nhất và lần khởi động lại trước đó. Các thiết bị không hỗ trợ retrieveSecurityLogs() sẽ trả về null. Nếu ứng dụng của bạn truy xuất nhật ký bằng cả retrievePreRebootSecurityLogs()retrieveSecurityLogs(), thì bạn cần kiểm tra các mục nhập trùng lặp.
Lưu ý: Tính năng này chỉ ghi lại hoạt động trên các thiết bị được quản lý hoàn toàn với một người dùng duy nhất hoặc người dùng được liên kết trên thiết bị. Tính năng này không hoạt động trên các thiết bị cá nhân vì tính năng này ghi lại hoạt động trên toàn thiết bị.

Chế độ cài đặt này có thể hữu ích trong việc kiểm tra sau sự kiện bảo mật vì nó ghi lại các loại hành động sau:

  • Mỗi khi ứng dụng mới khởi động. Điều này có thể giúp xác định xem có phần mềm độc hại nào bắt đầu bằng một ứng dụng bị xâm phạm hay không.
  • Số lần mở khoá không thành công trên một thiết bị. Điều này có thể xác định liệu có một vài lần mở khoá không thành công trong một khoảng thời gian ngắn hay không.
  • Các lệnh adb có khả năng gây hại khi người dùng kết nối thiết bị với máy tính bằng cáp USB.

Để biết thông tin chi tiết về cách đọc nhật ký, hãy xem SecurityLog.

Trong khi phát triển và kiểm thử, bạn có thể buộc hệ thống cung cấp mọi nhật ký bảo mật hiện có cho DPC của mình mà không phải đợi một lô đầy đủ. Trong Android 9.0 (API cấp 28) trở lên, hãy chạy lệnh Cầu gỡ lỗi Android (adb) sau đây trong thiết bị đầu cuối của bạn:

adb shell dpm force-security-logs

Hệ thống giới hạn tần suất bạn có thể sử dụng công cụ này và báo cáo mọi trường hợp chủ ý làm chậm ở đầu ra của thiết bị đầu cuối. Nếu có sẵn nhật ký, DPC của bạn sẽ nhận được lệnh gọi lại onSecurityLogsAvailable().

Yêu cầu báo cáo lỗi từ xa

DPC chạy ở chế độ chủ sở hữu thiết bị có thể yêu cầu từ xa báo cáo lỗi cho thiết bị của người dùng chỉ có một người dùng hoặc người dùng được liên kết. Báo cáo lỗi ghi lại hoạt động trên thiết bị ngay thời điểm yêu cầu báo cáo lỗi, nhưng cũng có thể bao gồm hoạt động từ vài giờ trước, tuỳ thuộc vào tần suất làm mới bộ đệm logcat.

Để yêu cầu báo cáo lỗi từ xa, DPC sẽ gọi requestBugreport():

Cấp quyền truy cập và xóa quyền truy cập vào chứng chỉ ứng dụng khách

Nếu một DPC chạy ở chế độ chủ sở hữu hồ sơ hoặc chủ sở hữu thiết bị cấp cho một ứng dụng bên thứ ba khả năng quản lý các chứng chỉ, thì ứng dụng đó có thể tự cấp quyền truy cập vào các chứng chỉ mà ứng dụng đó cài đặt mà không cần sự can thiệp của người dùng. Để cài đặt một chứng chỉ mà tất cả ứng dụng trong một hồ sơ đều có thể truy cập, hãy dùng installKeyPair().

Để biết các tham số cần định cấu hình, hãy xem installKeyPair(). Tính năng này hoạt động cùng với API hiện có để quản lý các chứng chỉ.

Kịch bản triển khai

Nếu không có phương thức installKeyPair():

  • Người dùng cần nhấn vào tên của chứng chỉ đó rồi nhấn vào Cho phép mỗi khi muốn cấp quyền truy cập vào một chứng chỉ.
  • Người dùng sẽ thấy lời nhắc khi cài đặt chứng chỉ và phải đặt tên cho chứng chỉ đó.

Với phương thức installKeyPair():

  • Người dùng không cần nhấn vào Cho phép mỗi khi muốn cấp quyền truy cập vào một chứng chỉ.
  • Người dùng không thể đổi tên chứng chỉ.
  • Quản trị viên có nhiều quyền kiểm soát hơn ở chỗ có thể chặn chứng chỉ cho những ứng dụng không nên có quyền truy cập vào các chứng chỉ cụ thể.

Loại bỏ chứng chỉ máy khách

Sau khi cấp quyền truy cập vào một chứng chỉ ứng dụng, để xoá từ xa chứng chỉ ứng dụng được cài đặt thông qua installKeyPair(), hãy gọi removeKeyPair().

Một DPC đang chạy ở chế độ chủ sở hữu thiết bị hoặc chế độ chủ sở hữu hồ sơ, hoặc trình cài đặt chứng chỉ được uỷ quyền có thể gọi removeKeyPair(). Thao tác này sẽ xoá một cặp khoá riêng tư và chứng chỉ được cài đặt trong một bí danh khoá riêng tư nhất định.

Kịch bản triển khai

Hãy sử dụng tính năng này nếu một tổ chức đang di chuyển sang một dạng chứng chỉ ứng dụng khách an toàn hơn. Nếu quản trị viên triển khai một chứng chỉ mới và việc phân phối chứng chỉ đó mất một khoảng thời gian đáng kể, thì quản trị viên này có thể thu hồi các chứng chỉ không dùng nữa sau khi quá trình di chuyển hoàn tất.

Đã đặt lại mật mã an toàn

DPC của bạn có thể đặt lại mật khẩu của người dùng bằng cách cho phép thay đổi bằng một mã thông báo bảo mật, đã được đăng ký trước. Chủ sở hữu thiết bị và chủ sở hữu hồ sơ có thể gọi các API đặt lại mật mã bảo mật để thay đổi mật khẩu của thiết bị và hồ sơ công việc tương ứng. Tính năng đặt lại mật mã an toàn sẽ thay thế resetPassword() với các điểm cải tiến sau:

Bạn nên sử dụng tính năng đặt lại mật mã bảo mật nếu bản dựng DPC của bạn nhắm đến Android 8.0 (API cấp 26) trở lên. Thao tác gọi resetPassword() sẽ gửi ra một SecurityException trong các DPC nhắm đến Android 8.0 trở lên, vì vậy, bạn có thể cần phải cập nhật DPC của mình.

Thiết lập và kích hoạt mã thông báo

DPC của bạn cần đặt và kích hoạt mã thông báo trước khi đặt lại mật khẩu. Vì DPC của bạn có thể không sử dụng được mã thông báo ngay lập tức, nên bạn đã đặt mã thông báo trước thời điểm quản trị viên CNTT có thể cần sử dụng mã đó.

Mã thông báo đặt lại mật khẩu là một giá trị ngẫu nhiên mạnh được mã hoá và cần dài ít nhất 32 byte. Tạo mã thông báo cho từng thiết bị và hồ sơ. Đừng sử dụng lại hoặc chia sẻ các mã thông báo đã tạo.

Bạn nên lưu trữ mã thông báo hoặc phương tiện để giải mã mã thông báo đã mã hoá trên máy chủ. Nếu bạn lưu trữ cục bộ mã thông báo trong bộ nhớ được mã hoá dành cho thông tin đăng nhập, thì DPC của bạn không thể đặt lại mật khẩu cho đến khi người dùng mở khoá thiết bị hoặc hồ sơ. Nếu bạn lưu trữ mã thông báo cục bộ trong bộ nhớ được mã hoá của thiết bị và mã này bị xâm phạm, thì kẻ tấn công có thể sử dụng mã thông báo này để giành quyền truy cập vào hồ sơ công việc hoặc người dùng chính.

Bạn có thể tạo mã thông báo mới trong DPC hoặc tìm nạp mã thông báo từ máy chủ. Ví dụ bên dưới cho thấy một DPC tự tạo một mã thông báo và báo cáo mã đó cho một máy chủ:

Kotlin

val token = ByteArray(32)

// Generate a new token
val random = SecureRandom()
random.nextBytes(token)

// Set the token to use at a later date
val success: Boolean
success = dpm.setResetPasswordToken(DeviceAdminReceiver.getComponentName(context), token)

// Activate the token and update success variable...

// Store the token on a server
if (success) {
 sendTokenToServer(token)
}

Java

byte token[] = new byte[32]; // Minimum size token accepted

// Generate a new token
SecureRandom random = new SecureRandom();
random.nextBytes(token);

// Set the token to use at a later date
boolean success;
success = dpm.setResetPasswordToken(DeviceAdminReceiver.getComponentName(getContext()), token);

// Activate the token and update success variable ...

// Store the token on a server
if (success) {
 sendTokenToServer(token);
}

Trong hầu hết các trường hợp, DPC của bạn cần kích hoạt mã thông báo sau khi thiết lập. Tuy nhiên, khi người dùng không có mật khẩu màn hình khoá, hệ thống sẽ kích hoạt một mã thông báo ngay lập tức. Để kích hoạt mã thông báo, hãy yêu cầu người dùng xác nhận thông tin đăng nhập của họ. DPC của bạn có thể gọi phương thức KeyguardManager createConfirmDeviceCredentialIntent() để nhận Intent bắt đầu xác nhận. Giải thích cho người dùng thiết bị trong giao diện người dùng, lý do bạn yêu cầu họ xác thực. Đoạn mã dưới đây cho biết cách bạn có thể kích hoạt một mã thông báo trong DPC:

Kotlin

// In your DPC, you'll need to localize the user prompt
val ACTIVATE_TOKEN_PROMPT = "Use your credentials to enable remote password reset"
val ACTIVATE_TOKEN_REQUEST = 1

// Create or fetch a token and set it in setResetPasswordToken() ...
val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
val confirmIntent = keyguardManager.createConfirmDeviceCredentialIntent(null, ACTIVATE_TOKEN_PROMPT)

if (confirmIntent != null) {
 startActivityForResult(confirmIntent, ACTIVATE_TOKEN_REQUEST)
 // Check your onActivityResult() callback for RESULT_OK
} else {
 // Null means the user doesn't have a lock screen so the token is already active.
 // Call isResetPasswordTokenActive() if you need to confirm
}

Java

// In your DPC, you'll need to localize the user prompt
static final String ACTIVATE_TOKEN_PROMPT =
 "Use your credentials to enable remote password reset";
static final int ACTIVATE_TOKEN_REQUEST = 1;

// Create or fetch a token and set it in setResetPasswordToken() ...

KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
Intent confirmIntent = keyguardManager.createConfirmDeviceCredentialIntent(
  null, ACTIVATE_TOKEN_PROMPT);

if (confirmIntent != null) {
 startActivityForResult(confirmIntent, ACTIVATE_TOKEN_REQUEST);
 // Check your onActivityResult() callback for RESULT_OK
} else {
 // Null means the user doesn't have a lock screen so the token is already active.
 // Call isResetPasswordTokenActive() if you need to confirm
}

Bạn cần kích hoạt mã thông báo mà DPC của bạn đặt trước khi khởi động lại thiết bị. Android lưu trữ một mã thông báo chưa kích hoạt trong bộ nhớ và không duy trì mã thông báo đó sau khi khởi động lại. Nếu người dùng khởi động lại thiết bị trước khi kích hoạt mã thông báo, thì DPC của bạn có thể đặt lại mã thông báo đó hoặc tạo một mã thông báo mới.

DPC của bạn có thể xác nhận mã thông báo đang hoạt động bằng cách gọi isResetPasswordTokenActive() và kiểm tra kết quả là true.

Sau khi DPC đặt và kích hoạt mã thông báo, mã đó sẽ có hiệu lực cho đến khi DPC xoá hoặc thay thế mã thông báo (hoặc thiết bị được đặt lại về trạng thái ban đầu). Mã thông báo độc lập với mật khẩu và không bị ảnh hưởng khi người dùng thay đổi hoặc xoá mật khẩu.

Xoá mã thông báo

Bạn có thể gọi clearResetPasswordToken() để xoá mã thông báo mà DPC của bạn đã đặt trước đó. Có thể bạn cần thu hồi mã thông báo bị xâm phạm hoặc xoá tính năng đặt lại mật khẩu. Mẫu dưới đây cho biết cách bạn có thể thực hiện việc này trong DPC:

Kotlin

val dpm = getDpm()
val admin = DeviceAdminReceiver.getComponentName(requireActivity())

// Clear the token
if (!dpm.clearResetPasswordToken(admin)) {
 // Report the failure and possibly try later ...
}

Java

DevicePolicyManager dpm = getDpm();
ComponentName admin = DeviceAdminReceiver.getComponentName(getActivity());

// Clear the token
if (!dpm.clearResetPasswordToken(admin)) {
 // Report the failure and possibly try later ...
}

Đặt lại mật khẩu

Khi quản trị viên CNTT cần đặt lại mật khẩu, hãy gọi resetPasswordWithToken() rồi truyền mã thông báo mà DPC bạn đã đặt và kích hoạt trước:

Kotlin

val token: ByteArray = getTokenFromServer()
val newPassword = "password"

try {
 val result: Boolean = dpm.resetPasswordWithToken(
 DeviceAdminReceiver.getComponentName(requireContext()),
 newPassword,
 token,
 0
 )

 if (result) {
 // The password is now 'password'
 } else {
 // Using 'password' doesn't meet password restrictions
 }
} catch (e: IllegalStateException) {
 // The token doesn't match the one set earlier.
}

Java

byte token[] = getTokenFromServer();
String newPassword = "password";

try {
 boolean result = dpm.resetPasswordWithToken(
  DeviceAdminReceiver.getComponentName(getContext()), newPassword, token, 0);

 if (result) {
 // The password is now 'password'
 } else {
 // Using `password` doesn't meet password restrictions
 }
} catch (IllegalStateException e) {
 // The token doesn't match the one set earlier.
}

Lệnh gọi đến resetPasswordWithToken() trả về false và mật khẩu không thay đổi khi mật khẩu mới không đáp ứng các điều kiện ràng buộc sau:

  • Số ký tự đáp ứng mọi giới hạn về độ dài tối thiểu của mật khẩu. Gọi getPasswordMinimumLength() để biết liệu quản trị viên CNTT có đặt quy tắc ràng buộc về độ dài hay không.
  • Phạm vi và độ phức tạp của ký tự trong mật khẩu đáp ứng giới hạn về thành phần. Gọi getPasswordQuality() để biết liệu quản trị viên CNTT có đặt quy tắc ràng buộc đối với thành phần hay không.

Nếu các quy tắc ràng buộc về chất lượng mật khẩu không yêu cầu đặt mật khẩu, thì bạn có thể truyền null hoặc một chuỗi trống đến resetPasswordWithToken() để xoá mật khẩu.

Thử thách bảo mật hồ sơ công việc

DPC chạy ở chế độ chủ sở hữu hồ sơ có thể yêu cầu người dùng chỉ định một thách thức về bảo mật cho các ứng dụng chạy trong hồ sơ công việc. Hệ thống cho thấy thách thức về bảo mật khi người dùng cố gắng mở bất kỳ ứng dụng công việc nào. Nếu người dùng hoàn tất thành công thử thách bảo mật, thì hệ thống sẽ mở khoá hồ sơ công việc và giải mã hồ sơ đó nếu cần.

Cách hoạt động của thử thách bảo mật hồ sơ công việc

  1. Nếu DPC gửi ý định ACTION_SET_NEW_PASSWORD, thì hệ thống sẽ nhắc người dùng thiết lập thử thách bảo mật.
  2. DPC cũng có thể gửi ý định ACTION_SET_NEW_PARENT_PROFILE_PASSWORD để nhắc người dùng đặt phương thức khoá thiết bị.

DPC có thể đặt chính sách mật khẩu cho thử thách công việc khác với chính sách cho các mật khẩu khác của thiết bị. Ví dụ: độ dài tối thiểu cho phản hồi thử thách trên thiết bị có thể khác với độ dài cần thiết cho mật khẩu khác. DPC đặt các chính sách xác thực bằng các phương thức DevicePolicyManager thông thường, chẳng hạn như setPasswordQuality()setPasswordMinimumLength().

Những yếu tố nên cân nhắc

  • DPC có thể đặt lại mật khẩu trên hồ sơ công việc nhưng không thể đặt lại mật khẩu (cá nhân) của thiết bị. Nếu người dùng chọn đặt mật khẩu công việc và mật khẩu cá nhân giống nhau, thì resetPassword() trên hồ sơ công việc sẽ chỉ đặt lại mật khẩu trên hồ sơ công việc và mật khẩu sẽ không giống với mật khẩu cho màn hình khoá của thiết bị.
  • DPC có thể tuỳ chỉnh màn hình thông tin xác thực cho thử thách công việc bằng cách sử dụng setOrganizationColor()setOrganizationName().
  • Quản trị viên thiết bị không thể dùng resetPassword() để xoá mật khẩu hoặc thay đổi mật khẩu đã đặt. Quản trị viên thiết bị vẫn có thể đặt mật khẩu, nhưng chỉ khi thiết bị không có mật khẩu, mã PIN hoặc hình mở khoá.

Để biết thêm thông tin, hãy xem getParentProfileInstance() và tài liệu tham khảo trong DevicePolicyManager.