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

Android Security 最前線

YANOKURO
March 10, 2017

Android Security 最前線

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

YANOKURO

March 10, 2017
Tweet

Other Decks in Technology

Transcript

  1. Android Security ࠷લઢʁʁ Android Nougat ʹ͸ɺ SecurityपΓͷΞοϓσʔτ͕͍ͬͺ͍ʂʂ ɾUsing Scoped Directory

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

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

    ɹɹ֎෦ετϨʔδશͯ΁ͷΞΫηεΛڐՄɻ APP/FW Dir root Dir A Dir B Dir C Request Permit
  4. Using Scoped Directory Access ৽نAPI ɾStorageVolume - ಛఆͷϢʔβʔͷڞ༗/֎෦ετϨʔδϘϦϡʔϜʹؔ͢Δ৘ใɻ - createAccessIntent()

    - ϢʔβʔͷঝೝΛಘͨޙɺඪ४ͷετϨʔδσΟϨΫτϦ·ͨ͸ϘϦϡʔϜશମ ΁ͷΞΫηεΛ༩͑ΔͨΊͷΠϯςϯτΛ࡞੒͢Δɻ - getState() - ετϨʔδϘϦϡʔϜͷঢ়ଶΛऔಘ͢Δɻ
  5. 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);
  6. 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; }
  7. 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 };
  8. 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)) { }
  9. 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͕ೖ͍ͬͯΔ } }
  10. 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>
  11. Direct Boot // ProtectedStorage΁ͷอଘ final Context deviceContext = getApplicationContext().createDeviceProtectedStorageContext(); deviceContext.moveSharedPreferencesFrom(context,

    PREFERENCES_NAME)); SharedPreferences sp = deviceContext .getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
  12. 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; } }
  13. Android 6.0 Ҏલɿ Android 7.0ɿ Direct Boot Android Boot Unlocked

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

    ai.deviceProtectedDataDir); # deviceProtectedDataDir: /data/user_de/0/com.yanokuro.directboot
  15. 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>
  16. 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>
  17. 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>
  18. EOF