Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android Security 最前線

3282c1e7c6a3ce6e7014499107cf3965?s=47 YANOKURO
March 10, 2017

Android Security 最前線

AndroidNougatで追加されたSecurity関係のAPIの使い方をまとめたものです。

3282c1e7c6a3ce6e7014499107cf3965?s=128

YANOKURO

March 10, 2017
Tweet

Transcript

  1. Android Security ࠷લઢʂ Naoki Yano

  2. ໼໺ ௚ً Ϡϑʔגࣜձࣾ GYAOגࣜձࣾ Android Framework / Application / CTS

    / Driver Engineer Androidྺ 3೥ ؔ౦ྺ 2೥
  3. Android Security ࠷લઢʁʁ Android Nougat ʹ͸ɺ SecurityपΓͷΞοϓσʔτ͕͍ͬͺ͍ʂʂ ɾUsing Scoped Directory

    Access ɾDirect Boot ɾNetwork Security Config ɾKey Attestation ɾAPK Signature Scheme v2 ͍ͭͰ΋࢖͑ΔΑ͏ʹ ४උ͓ͯ͘͜͠ͱ͕େࣄʂʂ
  4. Android N Security Using Scoped Directory Access Direct Boot Network

    Security Config Key Attestation APK Signature Scheme v2
  5. Using Scoped Directory Access Android 6.0 Ҏલɿ ɹɹManifestʹPermissionΛఆٛ + PermissionRequest

    ɹɹ֎෦ετϨʔδશͯ΁ͷΞΫηεΛڐՄɻ APP/FW Dir root Dir A Dir B Dir C Request Permit
  6. Using Scoped Directory Access Android 7.0ɿ ɹɹΞΫηε͍ͨ͠σΟϨΫτϦͷStorageVolumeΛ࡞੒͠ɺRequestΛ౤͛Δɻ ɹɹಛఆͷσΟϨΫτϦ΁ͷΞΫηεͷΈڐՄ͢Δɻ APP/FW Dir

    root Dir A Dir B Dir C Request Permit
  7. Using Scoped Directory Access ৽نAPI ɾStorageVolume - ಛఆͷϢʔβʔͷڞ༗/֎෦ετϨʔδϘϦϡʔϜʹؔ͢Δ৘ใɻ - createAccessIntent()

    - ϢʔβʔͷঝೝΛಘͨޙɺඪ४ͷετϨʔδσΟϨΫτϦ·ͨ͸ϘϦϡʔϜશମ ΁ͷΞΫηεΛ༩͑ΔͨΊͷΠϯςϯτΛ࡞੒͢Δɻ - getState() - ετϨʔδϘϦϡʔϜͷঢ়ଶΛऔಘ͢Δɻ
  8. Using Scoped Directory Access ৽نAPI ɾStorageManager ඞཁͳStorageVolumeΛऔಘ͢Δɻ - getPrimaryStorageVolume() -

    getStorageVolume(File) - getStorageVolumes()
  9. Using Scoped Directory Access // ΞΫηεݖ͕ඞཁͳstorageVolumeͷऔಘ StorageManager sm = getSystemService(StorageManager.class);


    StorageVolume sv = sm.getPrimaryStorageVolume(); // ϢʔβʔঝೝΛಘΔͨΊͷIntentΛੜ੒
 Intent i = sv.createAccessIntent(Environment.DIRECTORY_MUSIC);
 // IntentΛStartActivityForResultͰ౤͛Δ startActivityForResult(i, REQUEST_CODE);
  10. StorageVolume#createAccessIntent(String) package android.os.storage; public final class StorageVolume implements Parcelable {

    … public @Nullable Intent createAccessIntent(String directoryName) { if ((isPrimary() && directoryName == null) || (directoryName != null && !Environment.isStandardDirectory(directoryName))) { return null; } final Intent intent = new Intent(ACTION_OPEN_EXTERNAL_DIRECTORY); intent.putExtra(EXTRA_STORAGE_VOLUME, this); intent.putExtra(EXTRA_DIRECTORY_NAME, directoryName); return intent; }
  11. StorageVolume#createAccessIntent(String) package android.os; public class Environment { public static final

    String[] STANDARD_DIRECTORIES = { DIRECTORY_MUSIC, DIRECTORY_PODCASTS, DIRECTORY_RINGTONES, DIRECTORY_ALARMS, DIRECTORY_NOTIFICATIONS, DIRECTORY_PICTURES, DIRECTORY_MOVIES, DIRECTORY_DOWNLOADS, DIRECTORY_DCIM, DIRECTORY_DOCUMENTS };
  12. OpenExternalDirectoryActivity package com.android.documentsui; public class OpenExternalDirectoryActivity extends Activity { …

    public void onCreate(Bundle savedInstanceState) { // σΟϨΫτϦ͕ࢦఆ͞Εͯͳ͍৔߹͸ɺrootͷݖݶΛऔಘ String directoryName = intent.getStringExtra(EXTRA_DIRECTORY_NAME ); if (directoryName == null) { directoryName = DIRECTORY_ROOT; } //ύʔϛογϣϯऔಘࡁΈͰͳ͍͔֬ೝ final StorageVolume volume = (StorageVolume) storageVolume; if (getScopedAccessPermissionStatus(getApplicationContext(), getCallingPackage(), volume.getUuid(), directoryName) == PERMISSION_NEVER_ASK) { //Ϣʔβ֬ೝDialogදࣔ final int userId = UserHandle.myUserId(); if (!showFragment(this, userId, volume, directoryName)) { }
  13. Using Scoped Directory Access @Override public void onActivityResult(int requestCode, int

    resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) { // ̎ճ໨Ҏ߱͸μΠΞϩάΛग़͞ͳ͍Α͏ʹઃఆ getActivity().getContentResolver().takePersistableUriPermission(data.getData(), Intent.FLAG_GRANT_READ_URI_PERMISSION | ɹɹɹɹ Intent.FLAG_GRANT_WRITE_URI_PERMISSION); // read, write // data.getData() ʹΞΫηεݖΛಘͨσΟϨΫτϦͷURI͕ೖ͍ͬͯΔ } }
  14. Using Scoped Directory Access ɾײ૝ ɹɹɾσΟϨΫτϦຖʹΞΫηεڐՄΛඞཁͱ͢Δͷ͸ɺ ɹɹɹ࢖͏ଆͱͯ͠΋҆৺Ͱ͖Δɻ ɹɹɾϓϥΠϚϦετϨʔδͱͦΕҎ֎ͰAPIͷ࢖͍ํ͕ ɹɹɹมΘͬͯ͘ΔͷͰ஫ҙʂ

  15. Direct Boot Android 6.0 Ҏલɿ ɹɹ୺຤͕҉߸Խ͞Ε͍ͯΔ৔߹ɺطଘͷอଘઌ͸ɺ ɹɹϢʔβʔ͕ϩοΫΛղআͨ͠ޙʹ͚ͩ࢖༻Ͱ͖Δɻ APP/FW data/user Boot

    Unlock user key
  16. Direct Boot APP/FW user Boot Unlock Android 7.0ɿ ɹɹϩοΫղআ͞Ε͍ͯͳ͍ঢ়ଶͰ͸ɺμΠϨΫτϒʔτϞʔυͰಈ࡞͢Δɻ ɹɹ୺຤҉߸ԽετϨʔδʹΞΫηεͰ͖Δɻ

    user_de hard−backed key user key
  17. Direct Boot ৽نAPI ɾandroid:directBootAware ίϯϙʔωϯτ͕҉߸ԽରԠ͢ΔΑ͏ʹࢦఆ͢Δɻ ɾandroid.intent.action.LOCKED_BOOT_COMPLETED ୺຤҉߸ԽετϨʔδ͕࢖༻Մೳʹͳͬͨ͜ͱΛ௨஌͢Δɻ ɾContext#createDeviceProtectedStorageContext() ୺຤҉߸ԽετϨʔδʹΞΫηε͢ΔͨΊͷContextΛੜ੒͢Δɻ

  18. Direct Boot // ίϯϙʔωϯτ͕҉߸ԽରԠ͢ΔΑ͏ʹFlagΛͨͯΔ <receiver android:name=".BootBroadcastReceiver" android:exported="false" android:directBootAware="true"> <intent-filter> <action

    android:name="android.intent.action.LOCKED_BOOT_COMPLETED" /> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
  19. Direct Boot // ProtectedStorage΁ͷอଘ final Context deviceContext = getApplicationContext().createDeviceProtectedStorageContext(); deviceContext.moveSharedPreferencesFrom(context,

    PREFERENCES_NAME)); SharedPreferences sp = deviceContext .getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
  20. Direct Boot // LOCKED_BOOT_COMPLETEDΛड͚ͯσʔλΛऔಘ͢Δ public void onReceive(Context context, Intent intent)

    { boolean bootCompleted; String action = intent.getAction(); if (BuildCompat.isAtLeastN()) { bootCompleted = Intent.ACTION_LOCKED_BOOT_COMPLETED.equals(action); } else { bootCompleted = Intent.ACTION_BOOT_COMPLETED.equals(action); } if (!bootCompleted) { return; } }
  21. Android 6.0 Ҏલɿ Android 7.0ɿ Direct Boot Android Boot Unlocked

    Android Boot Unlocked BOOT_COMPLETED LOCKED_BOOT_COMPLETED USER_UNLOCKED BOOT_COMPLETED
  22. Direct Boot ApplicationInfo ai = getApplicationInfo(); Log.i(TAG, “deviceProtectedDataDir: ” +

    ai.deviceProtectedDataDir); # deviceProtectedDataDir: /data/user_de/0/com.yanokuro.directboot
  23. Direct Boot ɾײ૝ ɹɹɾ୺຤҉߸ԽετϨʔδͰ͸ɺηΩϡϦςΟϨϕϧ͕ ɹɹɹԼ͕ΔͨΊɺԿΛอଘ͢Δ͔ਫ਼͕ࠪඞཁɻ ɹɹɾBOOT_COMPLETE͕ݺ͹ΕΔҐஔ͕มΘͬͨΑɻ

  24. Network Security Config Android 7.0ɿ ΧελϜCAূ໌ॻΛ৴པ͢ΔͨΊͷ҆શͰ؆୯ͳAPIͷఏڙɻ σϑΥϧτͰ͸ɺϢʔβʔ͕௥Ճͨ͠CAΛ৴པ͠ͳ͍ɻ

  25. Network Security Config ɾres/xml/network_security_config Λ࡞੒ ɾmanifestʹ௥ه

  26. Network Security Config <?xml version="1.0" encoding="utf-8"?> <manifest ... > <application

    ... > <meta-data android:name="android.security.net.config" android:resource="@xml/network_security_config" /> </application> </manifest>
  27. Network Security ConfigɹΧελϜͷূ໌ػؔ <?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain>

    <trust-anchors> <certificates src="@raw/my_ca"/> </trust-anchors> </domain-config> </network-security-config>
  28. Network Security Configɹূ໌ॻͷఆٛ <trust-anchors> // ΞϓϦ͕͍࣋ͬͯΔCAূ໌ॻΛ࢖༻ <certificates src="@raw/my_ca"/> // γεςϜσϑΥϧτͷCAূ໌ॻΛ࢖༻

    <certificates src="system"/> // Ϣʔβ͕௥Ճͨ͠CAূ໌ॻΛ࢖༻ <certificates src="user"/> </trust-anchors>
  29. Network Security Configɹσόοά༻ debuggable=true <?xml version="1.0" encoding="utf-8"?> <network-security-config> <debug-overrides> <trust-anchors>

    <certificates src="@raw/debug_ca"/> </trust-anchors> </debug-overrides> </network-security-config>
  30. Network Security ConfigɹΫϦΞςΩετͷ௨৴Λېࢭ <?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config usesCleartextTraffic="false"> <domain

    includeSubdomains="true">secure.example.com</ domain> </domain-config> </network-security-config>
  31. Network Security Configɹߏ੒ϑΝΠϧ <?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config> ... </base-config>

    <domain-config> ... </domain-config> <debug-overrides> ... </debug-overrides> </network-security-config>
  32. Network Security ConfigɹAndroid 7.0 default <base-config usesCleartextTraffic="true"> <trust-anchors> <certificates src="system"

    /> </trust-anchors> </base-config>
  33. Network Security ConfigɹAndroid 7.0 ະຬ <base-config usesCleartextTraffic="true"> <trust-anchors> <certificates src="system"

    /> <certificates src="user" /> </trust-anchors> </base-config>
  34. Network Security Config ɾײ૝ ɹɹɾઃఆΞϓϦ͔ΒCAೖΕΔඞཁ͕ͳ͘ͳͬͯخ͍͠ɻ ɹɹɾ7.0ΑΓલͰ΋࢖͑Δͱ͍͍ͳɻ

  35. ·ͱΊ ͦΕͧΕ஫ҙϙΠϯτ͸͋Δ͕ɺؾΛ͚ͭͯ࢖͑͹ΑΓη ΩϡΞͳΞϓϦ͕࡞Εͦ͏ɻ ֤ػೳͷಈ͖Λ͔ͬ͠Γཧղͯ͠։ൃ͠·͠ΐ͏ɻ

  36. EOF