Slide 1

Slide 1 text

Android Security ࠷લઢʂ Naoki Yano

Slide 2

Slide 2 text

໼໺ ௚ً Ϡϑʔגࣜձࣾ GYAOגࣜձࣾ Android Framework / Application / CTS / Driver Engineer Androidྺ 3೥ ؔ౦ྺ 2೥

Slide 3

Slide 3 text

Android Security ࠷લઢʁʁ Android Nougat ʹ͸ɺ SecurityपΓͷΞοϓσʔτ͕͍ͬͺ͍ʂʂ ɾUsing Scoped Directory Access ɾDirect Boot ɾNetwork Security Config ɾKey Attestation ɾAPK Signature Scheme v2 ͍ͭͰ΋࢖͑ΔΑ͏ʹ ४උ͓ͯ͘͜͠ͱ͕େࣄʂʂ

Slide 4

Slide 4 text

Android N Security Using Scoped Directory Access Direct Boot Network Security Config Key Attestation APK Signature Scheme v2

Slide 5

Slide 5 text

Using Scoped Directory Access Android 6.0 Ҏલɿ ɹɹManifestʹPermissionΛఆٛ + PermissionRequest ɹɹ֎෦ετϨʔδશͯ΁ͷΞΫηεΛڐՄɻ APP/FW Dir root Dir A Dir B Dir C Request Permit

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

Using Scoped Directory Access ৽نAPI ɾStorageVolume - ಛఆͷϢʔβʔͷڞ༗/֎෦ετϨʔδϘϦϡʔϜʹؔ͢Δ৘ใɻ - createAccessIntent() - ϢʔβʔͷঝೝΛಘͨޙɺඪ४ͷετϨʔδσΟϨΫτϦ·ͨ͸ϘϦϡʔϜશମ ΁ͷΞΫηεΛ༩͑ΔͨΊͷΠϯςϯτΛ࡞੒͢Δɻ - getState() - ετϨʔδϘϦϡʔϜͷঢ়ଶΛऔಘ͢Δɻ

Slide 8

Slide 8 text

Using Scoped Directory Access ৽نAPI ɾStorageManager ඞཁͳStorageVolumeΛऔಘ͢Δɻ - getPrimaryStorageVolume() - getStorageVolume(File) - getStorageVolumes()

Slide 9

Slide 9 text

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);

Slide 10

Slide 10 text

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; }

Slide 11

Slide 11 text

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 };

Slide 12

Slide 12 text

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)) { }

Slide 13

Slide 13 text

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͕ೖ͍ͬͯΔ } }

Slide 14

Slide 14 text

Using Scoped Directory Access ɾײ૝ ɹɹɾσΟϨΫτϦຖʹΞΫηεڐՄΛඞཁͱ͢Δͷ͸ɺ ɹɹɹ࢖͏ଆͱͯ͠΋҆৺Ͱ͖Δɻ ɹɹɾϓϥΠϚϦετϨʔδͱͦΕҎ֎ͰAPIͷ࢖͍ํ͕ ɹɹɹมΘͬͯ͘ΔͷͰ஫ҙʂ

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

Direct Boot // ίϯϙʔωϯτ͕҉߸ԽରԠ͢ΔΑ͏ʹFlagΛͨͯΔ

Slide 19

Slide 19 text

Direct Boot // ProtectedStorage΁ͷอଘ final Context deviceContext = getApplicationContext().createDeviceProtectedStorageContext(); deviceContext.moveSharedPreferencesFrom(context, PREFERENCES_NAME)); SharedPreferences sp = deviceContext .getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);

Slide 20

Slide 20 text

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; } }

Slide 21

Slide 21 text

Android 6.0 Ҏલɿ Android 7.0ɿ Direct Boot Android Boot Unlocked Android Boot Unlocked BOOT_COMPLETED LOCKED_BOOT_COMPLETED USER_UNLOCKED BOOT_COMPLETED

Slide 22

Slide 22 text

Direct Boot ApplicationInfo ai = getApplicationInfo(); Log.i(TAG, “deviceProtectedDataDir: ” + ai.deviceProtectedDataDir); # deviceProtectedDataDir: /data/user_de/0/com.yanokuro.directboot

Slide 23

Slide 23 text

Direct Boot ɾײ૝ ɹɹɾ୺຤҉߸ԽετϨʔδͰ͸ɺηΩϡϦςΟϨϕϧ͕ ɹɹɹԼ͕ΔͨΊɺԿΛอଘ͢Δ͔ਫ਼͕ࠪඞཁɻ ɹɹɾBOOT_COMPLETE͕ݺ͹ΕΔҐஔ͕มΘͬͨΑɻ

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

Network Security Config

Slide 27

Slide 27 text

Network Security ConfigɹΧελϜͷূ໌ػؔ example.com

Slide 28

Slide 28 text

Network Security Configɹূ໌ॻͷఆٛ // ΞϓϦ͕͍࣋ͬͯΔCAূ໌ॻΛ࢖༻ // γεςϜσϑΥϧτͷCAূ໌ॻΛ࢖༻ // Ϣʔβ͕௥Ճͨ͠CAূ໌ॻΛ࢖༻

Slide 29

Slide 29 text

Network Security Configɹσόοά༻ debuggable=true

Slide 30

Slide 30 text

Network Security ConfigɹΫϦΞςΩετͷ௨৴Λېࢭ secure.example.com domain>

Slide 31

Slide 31 text

Network Security Configɹߏ੒ϑΝΠϧ ... ... ...

Slide 32

Slide 32 text

Network Security ConfigɹAndroid 7.0 default

Slide 33

Slide 33 text

Network Security ConfigɹAndroid 7.0 ະຬ

Slide 34

Slide 34 text

Network Security Config ɾײ૝ ɹɹɾઃఆΞϓϦ͔ΒCAೖΕΔඞཁ͕ͳ͘ͳͬͯخ͍͠ɻ ɹɹɾ7.0ΑΓલͰ΋࢖͑Δͱ͍͍ͳɻ

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

EOF