שיפור האבטחה באמצעות כללי מדיניות לניהול מכשירים

הוצאה משימוש של מנהל המכשיר. חלק מכללי המדיניות של האדמין סומנו ככאלה שהוצאו משימוש במהלך ההפעלה על ידי אדמין של המכשיר. למידע נוסף ולראות את אפשרויות ההעברה, אפשר לעיין במאמר הוצאה משימוש של מנהל המכשיר.

החל מ-Android 2.2 (רמת API 8), פלטפורמת Android מציעה ניהול מכשירים ברמת המערכת יכולות באמצעות ממשקי ה-API לניהול מכשירים.

בשיעור הזה תלמדו איך ליצור אפליקציה מבוססת-אבטחה שמנהלת את הגישה אל את התוכן שלו באמצעות אכיפה של כללי המדיניות לניהול מכשירים. באופן ספציפי, ניתן להגדיר את האפליקציה כך שהיא מבטיחה שהוגדרה סיסמה לנעילת מסך בעוצמה מספקת לפני הצגת תוכן שמוגבל למשתמש.

הגדרת המדיניות והצהרה שלה

קודם כול, צריך להגדיר את סוגי המדיניות שנתמכים ברמת הפונקציונליות. כללי המדיניות עשויים כיסוי חוזק סיסמה לנעילת מסך, זמן קצוב לתפוגה, הצפנה וכו'

עליך להצהיר על קבוצת כללי המדיניות שנבחרה שהאפליקציה תיאכף, בקטע קובץ res/xml/device_admin.xml. המניפסט של Android צריך גם להתייחס אל המדיניות המוצהרת מוגדרת.

כל המדיניות המוצהרת תואמת למספר מסוים של שיטות קשורות של מדיניות מכשירים במסגרת DevicePolicyManager (הגדרת אורך סיסמה מינימלי ומספר מינימלי של (אותיות רישיות הן שתי דוגמאות). אם אפליקציה מנסה להפעיל שיטות לא הוצהרה מדיניות תואמת ב-XML. התוצאה תהיה SecurityException בזמן הריצה. הרשאות אחרות, כמו force-lock, זמינים אם יש כוונה לנהל את האפליקציה סוגי מדיניות אחרים. כמו שתראו מאוחר יותר, כחלק מתהליך ההפעלה של מנהל המכשיר, רשימת כללי המדיניות המוצהרים תוצג למשתמש במסך מערכת.

קטע הקוד הבא מצהיר על מדיניות הגבלת הסיסמאות ב-res/xml/device_admin.xml:

<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-policies>
        <limit-password />
    </uses-policies>
</device-admin>

קובץ ה-XML של הצהרת המדיניות שיש הפניה אליו במניפסט של Android:

<receiver android:name=".Policy$PolicyAdmin"
    android:permission="android.permission.BIND_DEVICE_ADMIN">
    <meta-data android:name="android.app.device_admin"
        android:resource="@xml/device_admin" />
    <intent-filter>
        <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
    </intent-filter>
</receiver>

יצירת קבלה לניהול של מכשיר

ניתן ליצור מקלט שידורים של ניהול מכשירים, שיקבל התראות על אירועים שקשורים לכללי המדיניות שעליהם הצהרת לתמוך. אפליקציה יכולה לשנות באופן סלקטיבי שיטות קריאה חוזרת (callback).

באפליקציה לדוגמה, התכונה 'ניהול מכשירים', כאשר מנהל המכשיר מושבת על ידי משתמש, המדיניות שהוגדרה תימחק מההעדפה המשותפת. כדאי לך להטמיע של הלוגיקה העסקית שרלוונטית לתרחיש לדוגמה שלכם. לדוגמה, היישום עשוי לקחת לצמצום סיכוני האבטחה באמצעות הטמעה של שילוב כלשהו של מחיקת מידע אישי רגיש המכשיר, השבתת הסנכרון מרחוק, שליחת התראות למנהל המערכת וכו'.

כדי שמקלט השידור יפעל, יש לרשום אותו במניפסט של Android כפי שמוצג בקטע הקוד שלמעלה.

Kotlin

class PolicyAdmin : DeviceAdminReceiver() {

    override fun onDisabled(context: Context, intent: Intent) {
        // Called when the app is about to be deactivated as a device administrator.
        // Deletes previously stored password policy.
        super.onDisabled(context, intent)
        context.getSharedPreferences(APP_PREF, Activity.MODE_PRIVATE).edit().apply {
            clear()
            apply()
        }
    }
}

Java

public static class PolicyAdmin extends DeviceAdminReceiver {

    @Override
    public void onDisabled(Context context, Intent intent) {
        // Called when the app is about to be deactivated as a device administrator.
        // Deletes previously stored password policy.
        super.onDisabled(context, intent);
        SharedPreferences prefs = context.getSharedPreferences(APP_PREF, Activity.MODE_PRIVATE);
        prefs.edit().clear().commit();
    }
}

הפעלת מנהל המכשיר

לפני האכיפה של מדיניות כלשהי, המשתמש צריך להפעיל את האפליקציה באופן ידני כמכשיר מנהל מערכת. קטע הקוד הבא מדגים איך להפעיל את פעילות ההגדרות שבה המשתמש יכול להפעיל את האפליקציה שלך. מומלץ לכלול את טקסט ההסבר כדי להדגיש למשתמשים למה האפליקציה מבקשת להיות מנהל מכשיר, על ידי ציון עוד EXTRA_ADD_EXPLANATION בכוונה.

איור 1. מסך ההפעלה של המשתמש, שבו אפשר מספקים תיאור של מדיניות המכשיר.

Kotlin

if (!policy.isAdminActive()) {

    val activateDeviceAdminIntent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)

    activateDeviceAdminIntent.putExtra(
            DevicePolicyManager.EXTRA_DEVICE_ADMIN,
            policy.getPolicyAdmin()
    )

    // It is good practice to include the optional explanation text to
    // explain to user why the application is requesting to be a device
    // administrator. The system will display this message on the activation
    // screen.
    activateDeviceAdminIntent.putExtra(
            DevicePolicyManager.EXTRA_ADD_EXPLANATION,
            resources.getString(R.string.device_admin_activation_message)
    )

    startActivityForResult(activateDeviceAdminIntent, REQ_ACTIVATE_DEVICE_ADMIN)
}

Java

if (!policy.isAdminActive()) {

    Intent activateDeviceAdminIntent =
        new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);

    activateDeviceAdminIntent.putExtra(
        DevicePolicyManager.EXTRA_DEVICE_ADMIN,
        policy.getPolicyAdmin());

    // It is good practice to include the optional explanation text to
    // explain to user why the application is requesting to be a device
    // administrator. The system will display this message on the activation
    // screen.
    activateDeviceAdminIntent.putExtra(
        DevicePolicyManager.EXTRA_ADD_EXPLANATION,
        getResources().getString(R.string.device_admin_activation_message));

    startActivityForResult(activateDeviceAdminIntent,
        REQ_ACTIVATE_DEVICE_ADMIN);
}

אם המשתמש יבחר באפשרות 'הפעלה', האפליקציה הופכת למנהל מכשיר ויכולה להתחיל הגדרה ואכיפה של המדיניות.

האפליקציה גם צריכה להיות מוכנה להתמודד עם מצבים שבהם המשתמש נוטש תהליך ההפעלה על ידי לחיצה על הלחצן 'ביטול', על המקש 'הקודם' או על מקש 'דף הבית'. לכן, צריכה להיות לוגיקה ל-onResume() בפעילות של הגדרת המדיניות כדי להעריך מחדש את התנאי ולהציג למשתמש את האפשרות 'הפעלת אדמין במכשיר' אם הדרושים.

הטמעה של ממשק השליטה במכשירים

לאחר שמנהל המכשיר יופעל, האפליקציה מגדירה את המכשיר מרכז המדיניות עם המדיניות המבוקשת. חשוב לזכור שכללי מדיניות חדשים מתווספים Android בכל גרסה. מומלץ לבצע בדיקות גרסאות באפליקציה אם משתמשים כללי מדיניות חדשים בזמן שתומכים בגרסאות ישנות של הפלטפורמה. לדוגמה, ערך המינימום לסיסמה המדיניות בנושא אותיות רישיות זמינה רק ב-API ברמה 11 (Honeycomb) ואילך. את הקוד הבא תדגים איך אפשר לבדוק את הגרסה בזמן הריצה.

Kotlin

private lateinit var dpm: DevicePolicyManager
private lateinit var policyAdmin: ComponentName

dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
policyAdmin = ComponentName(context, PolicyAdmin::class.java)

dpm.apply {
    setPasswordQuality(policyAdmin, PASSWORD_QUALITY_VALUES[passwordQuality])
    setPasswordMinimumLength(policyAdmin, passwordLength)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        setPasswordMinimumUpperCase(policyAdmin, passwordMinUpperCase)
    }
}

Java

DevicePolicyManager dpm = (DevicePolicyManager)
        context.getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName policyAdmin = new ComponentName(context, PolicyAdmin.class);

dpm.setPasswordQuality(policyAdmin, PASSWORD_QUALITY_VALUES[passwordQuality]);
dpm.setPasswordMinimumLength(policyAdmin, passwordLength);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    dpm.setPasswordMinimumUpperCase(policyAdmin, passwordMinUpperCase);
}

בשלב הזה האפליקציה יכולה לאכוף את המדיניות. למרות שאין לאפליקציה גישה לסיסמה של נעילת המסך שבה נעשה שימוש, דרך ממשק ה-API של מנהל מדיניות המכשיר הוא יכול לקבוע אם הסיסמה הקיימת עומדת במדיניות הנדרשת. אם יתברר שהמחרוזת הקיימת הסיסמה לנעילת המסך אינה מספיקה, ממשק ה-API לניהול המכשיר לא מקבל באופן אוטומטי לבצע את הפעולה המתוקנת. באחריות האפליקציה להפעיל את המערכת באופן מפורש מסך שינוי הסיסמה באפליקציית ההגדרות. מוצרים לדוגמה:

Kotlin

if (!dpm.isActivePasswordSufficient) {
    // Triggers password change screen in Settings.
    Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD).also { intent ->
        startActivity(intent)
    }
}

Java

if (!dpm.isActivePasswordSufficient()) {
    ...
    // Triggers password change screen in Settings.
    Intent intent =
        new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
    startActivity(intent);
}

בדרך כלל, המשתמש יכול לבחור מתוך אחד ממנגנוני הנעילה הזמינים, כמו 'ללא', 'קו ביטול נעילה', קוד אימות (נומרי) או סיסמה (אלפאנומרי). כשמוגדרת מדיניות סיסמאות, הסיסמאות סוגים חלשים יותר מאלה שהוגדרו במדיניות. לדוגמה, אם איכות הסיסמה ה'נומרית' מוגדרת. המשתמש יכול לבחור קוד אימות (נומרי) או סיסמה סיסמה (אלפאנומרית) בלבד.

לאחר שהמכשיר מאבטח כראוי על ידי הגדרת סיסמה מתאימה לנעילת מסך, האפליקציה שמאפשרות גישה לתוכן המאובטח.

Kotlin

when {
    !dpm.isAdminActive(policyAdmin) -> {
        // Activates device administrator.
        ...
    }
    !dpm.isActivePasswordSufficient -> {
        // Launches password set-up screen in Settings.
        ...
    }
    else -> {
        // Grants access to secure content.
        ...
        startActivity(Intent(context, SecureActivity::class.java))
    }
}

Java

if (!dpm.isAdminActive(..)) {
    // Activates device administrator.
    ...
} else if (!dpm.isActivePasswordSufficient()) {
    // Launches password set-up screen in Settings.
    ...
} else {
    // Grants access to secure content.
    ...
    startActivity(new Intent(context, SecureActivity.class));
}