Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Android Security 最前線
Search
YANOKURO
March 10, 2017
Technology
2
2.3k
Android Security 最前線
AndroidNougatで追加されたSecurity関係のAPIの使い方をまとめたものです。
YANOKURO
March 10, 2017
Tweet
Share
Other Decks in Technology
See All in Technology
Building Scalable Backend Services with Firebase
wisdommatt
0
110
Amazon Q Developerで.NET Frameworkプロジェクトをモダナイズしてみた
kenichirokimura
1
190
コロプラのオンボーディングを採用から語りたい
colopl
5
940
iPadOS18でフローティングタブバーを解除してみた
sansantech
PRO
1
120
GeometryReaderやスクロールを用いた表現と紐解き方
fumiyasac0921
0
100
完全自律型AIエージェントとAgentic Workflow〜ワークフロー構築という現実解
pharma_x_tech
0
320
KMP with Crashlytics
sansantech
PRO
0
240
FODにおけるホーム画面編成のレコメンド
watarukudo
PRO
2
240
あなたの人生も変わるかも?AWS認定2つで始まったウソみたいな話
iwamot
3
820
三菱電機で社内コミュニティを立ち上げた話
kurebayashi
1
350
30分でわかるデータ分析者のためのディメンショナルモデリング #datatechjp / 20250120
kazaneya
PRO
22
4.7k
AWSマルチアカウント統制環境のすゝめ / 20250115 Mitsutoshi Matsuo
shift_evolve
0
100
Featured
See All Featured
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
How to Ace a Technical Interview
jacobian
276
23k
Statistics for Hackers
jakevdp
797
220k
Practical Orchestrator
shlominoach
186
10k
Building Adaptive Systems
keathley
38
2.4k
Six Lessons from altMBA
skipperchong
27
3.6k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.8k
Become a Pro
speakerdeck
PRO
26
5.1k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
1.2k
jQuery: Nuts, Bolts and Bling
dougneiner
62
7.6k
How to train your dragon (web standard)
notwaldorf
89
5.8k
Unsuck your backbone
ammeep
669
57k
Transcript
Android Security ࠷લઢʂ Naoki Yano
ً Ϡϑʔגࣜձࣾ GYAOגࣜձࣾ Android Framework / Application / CTS
/ Driver Engineer Androidྺ 3 ؔ౦ྺ 2
Android Security ࠷લઢʁʁ Android Nougat ʹɺ SecurityपΓͷΞοϓσʔτ͕͍ͬͺ͍ʂʂ ɾUsing Scoped Directory
Access ɾDirect Boot ɾNetwork Security Config ɾKey Attestation ɾAPK Signature Scheme v2 ͍ͭͰ͑ΔΑ͏ʹ ४උ͓ͯ͘͜͠ͱ͕େࣄʂʂ
Android N Security Using Scoped Directory Access Direct Boot Network
Security Config Key Attestation APK Signature Scheme v2
Using Scoped Directory Access Android 6.0 Ҏલɿ ɹɹManifestʹPermissionΛఆٛ + PermissionRequest
ɹɹ֎෦ετϨʔδશͯͷΞΫηεΛڐՄɻ APP/FW Dir root Dir A Dir B Dir C Request Permit
Using Scoped Directory Access Android 7.0ɿ ɹɹΞΫηε͍ͨ͠σΟϨΫτϦͷStorageVolumeΛ࡞͠ɺRequestΛ͛Δɻ ɹɹಛఆͷσΟϨΫτϦͷΞΫηεͷΈڐՄ͢Δɻ APP/FW Dir
root Dir A Dir B Dir C Request Permit
Using Scoped Directory Access ৽نAPI ɾStorageVolume - ಛఆͷϢʔβʔͷڞ༗/֎෦ετϨʔδϘϦϡʔϜʹؔ͢Δใɻ - createAccessIntent()
- ϢʔβʔͷঝೝΛಘͨޙɺඪ४ͷετϨʔδσΟϨΫτϦ·ͨϘϦϡʔϜશମ ͷΞΫηεΛ༩͑ΔͨΊͷΠϯςϯτΛ࡞͢Δɻ - getState() - ετϨʔδϘϦϡʔϜͷঢ়ଶΛऔಘ͢Δɻ
Using Scoped Directory Access ৽نAPI ɾStorageManager ඞཁͳStorageVolumeΛऔಘ͢Δɻ - getPrimaryStorageVolume() -
getStorageVolume(File) - getStorageVolumes()
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);
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; }
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 };
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)) { }
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͕ೖ͍ͬͯΔ } }
Using Scoped Directory Access ɾײ ɹɹɾσΟϨΫτϦຖʹΞΫηεڐՄΛඞཁͱ͢Δͷɺ ɹɹɹ͏ଆͱͯ҆͠৺Ͱ͖Δɻ ɹɹɾϓϥΠϚϦετϨʔδͱͦΕҎ֎ͰAPIͷ͍ํ͕ ɹɹɹมΘͬͯ͘ΔͷͰҙʂ
Direct Boot Android 6.0 Ҏલɿ ɹɹ͕҉߸Խ͞Ε͍ͯΔ߹ɺطଘͷอଘઌɺ ɹɹϢʔβʔ͕ϩοΫΛղআͨ͠ޙʹ͚ͩ༻Ͱ͖Δɻ APP/FW data/user Boot
Unlock user key
Direct Boot APP/FW user Boot Unlock Android 7.0ɿ ɹɹϩοΫղআ͞Ε͍ͯͳ͍ঢ়ଶͰɺμΠϨΫτϒʔτϞʔυͰಈ࡞͢Δɻ ɹɹ҉߸ԽετϨʔδʹΞΫηεͰ͖Δɻ
user_de hard−backed key user key
Direct Boot ৽نAPI ɾandroid:directBootAware ίϯϙʔωϯτ͕҉߸ԽରԠ͢ΔΑ͏ʹࢦఆ͢Δɻ ɾandroid.intent.action.LOCKED_BOOT_COMPLETED ҉߸ԽετϨʔδ͕༻Մೳʹͳͬͨ͜ͱΛ௨͢Δɻ ɾContext#createDeviceProtectedStorageContext() ҉߸ԽετϨʔδʹΞΫηε͢ΔͨΊͷContextΛੜ͢Δɻ
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>
Direct Boot // ProtectedStorageͷอଘ final Context deviceContext = getApplicationContext().createDeviceProtectedStorageContext(); deviceContext.moveSharedPreferencesFrom(context,
PREFERENCES_NAME)); SharedPreferences sp = deviceContext .getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
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; } }
Android 6.0 Ҏલɿ Android 7.0ɿ Direct Boot Android Boot Unlocked
Android Boot Unlocked BOOT_COMPLETED LOCKED_BOOT_COMPLETED USER_UNLOCKED BOOT_COMPLETED
Direct Boot ApplicationInfo ai = getApplicationInfo(); Log.i(TAG, “deviceProtectedDataDir: ” +
ai.deviceProtectedDataDir); # deviceProtectedDataDir: /data/user_de/0/com.yanokuro.directboot
Direct Boot ɾײ ɹɹɾ҉߸ԽετϨʔδͰɺηΩϡϦςΟϨϕϧ͕ ɹɹɹԼ͕ΔͨΊɺԿΛอଘ͢Δ͔ਫ਼͕ࠪඞཁɻ ɹɹɾBOOT_COMPLETE͕ݺΕΔҐஔ͕มΘͬͨΑɻ
Network Security Config Android 7.0ɿ ΧελϜCAূ໌ॻΛ৴པ͢ΔͨΊͷ҆શͰ؆୯ͳAPIͷఏڙɻ σϑΥϧτͰɺϢʔβʔ͕Ճͨ͠CAΛ৴པ͠ͳ͍ɻ
Network Security Config ɾres/xml/network_security_config Λ࡞ ɾmanifestʹه
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>
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>
Network Security Configɹূ໌ॻͷఆٛ <trust-anchors> // ΞϓϦ͕͍࣋ͬͯΔCAূ໌ॻΛ༻ <certificates src="@raw/my_ca"/> // γεςϜσϑΥϧτͷCAূ໌ॻΛ༻
<certificates src="system"/> // Ϣʔβ͕Ճͨ͠CAূ໌ॻΛ༻ <certificates src="user"/> </trust-anchors>
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>
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>
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>
Network Security ConfigɹAndroid 7.0 default <base-config usesCleartextTraffic="true"> <trust-anchors> <certificates src="system"
/> </trust-anchors> </base-config>
Network Security ConfigɹAndroid 7.0 ະຬ <base-config usesCleartextTraffic="true"> <trust-anchors> <certificates src="system"
/> <certificates src="user" /> </trust-anchors> </base-config>
Network Security Config ɾײ ɹɹɾઃఆΞϓϦ͔ΒCAೖΕΔඞཁ͕ͳ͘ͳͬͯخ͍͠ɻ ɹɹɾ7.0ΑΓલͰ͑Δͱ͍͍ͳɻ
·ͱΊ ͦΕͧΕҙϙΠϯτ͋Δ͕ɺؾΛ͚ͭͯ͑ΑΓη ΩϡΞͳΞϓϦ͕࡞Εͦ͏ɻ ֤ػೳͷಈ͖Λ͔ͬ͠Γཧղͯ͠։ൃ͠·͠ΐ͏ɻ
EOF