Android Dev Summit, October 23-24: two days of technical content, directly from the Android team. Sign-up for livestream updates.

Konfigurasi keamanan jaringan

Fitur Konfigurasi Keamanan Jaringan memungkinkan aplikasi menyesuaikan setelan keamanan jaringan mereka dalam file konfigurasi deklaratif yang aman tanpa memodifikasi kode aplikasi. Setelan ini bisa dikonfigurasi untuk domain dan aplikasi tertentu. Kemampuan utama fitur ini adalah sebagai berikut:

  • Anchor kepercayaan kustom: Menyesuaikan Otoritas Sertifikat (CA) mana yang dipercaya untuk sambungan aman suatu aplikasi. Misalnya, mempercayai sertifikat tertentu yang ditandatangani sendiri atau membatasi kumpulan CA umum yang dipercaya aplikasi.
  • Penggantian khusus debug: Melakukan debug sambungan aman tanpa masalah di aplikasi tanpa menambah risiko pada basis yang diinstal.
  • Memilih tidak menggunakan traffic cleartext: Melindungi aplikasi dari penggunaan traffic cleartext yang tidak disengaja.
  • Pemasangan pin pada sertifikat: Membatasi sambungan aman aplikasi ke sertifikat tertentu.

Menambahkan file Konfigurasi Keamanan Jaringan

Fitur Konfigurasi Keamanan Jaringan menggunakan file XML, yang dapat Anda gunakan untuk menetapkan setelan aplikasi. Anda harus menyertakan sebuah entri dalam manifes aplikasi untuk menunjuk ke file ini. Kutipan kode berikut dari sebuah manifes menunjukkan cara membuat entri ini:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest ... >
        <application android:networkSecurityConfig="@xml/network_security_config"
                        ... >
            ...
        </application>
    </manifest>
    

Menyesuaikan CA tepercaya

Aplikasi mungkin perlu memercayai kumpulan CA kustom dan bukan default platform. Alasan yang paling umum dari hal ini adalah:

  • Menghubungkan ke host dengan otoritas sertifikat kustom, seperti CA yang ditandatangani sendiri atau dikeluarkan secara internal dalam sebuah perusahaan.
  • Membatasi kumpulan CA hanya untuk CA yang Anda percayai, bukan setiap CA yang telah diinstal sebelumnya.
  • Memercayai CA tambahan yang tidak disertakan dalam sistem.

Secara default, sambungan aman (menggunakan sejumlah protokol seperti TLS dan HTTPS) dari semua aplikasi mempercayai CA sistem yang telah diinstal sebelumnya, dan aplikasi yang menargetkan Android 6.0 (API level 23) dan versi lebih rendah juga mempercayai penyimpanan CA yang ditambahkan oleh pengguna secara default. Aplikasi dapat menyesuaikan sambungannya sendiri menggunakan base-config (untuk penyesuaian jangkauan aplikasi) atau domain-config (untuk penyesuaian per domain).

Mengonfigurasikan CA kustom

Anggaplah Anda ingin terhubung ke host Anda yang menggunakan sertifikat SSL yang ditandatangani sendiri atau ke host yang sertifikat SSL-nya dikeluarkan oleh CA non-publik yang Anda percaya, seperti CA internal perusahaan Anda.

res/xml/network_security_config.xml:

    <?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>
    

Tambahkan sertifikat CA non-publik atau yang ditandatangani sendiri (dalam format PEM atau DER) ke res/raw/my_ca.

Membatasi kumpulan CA tepercaya

Aplikasi yang tidak ingin mempercayai semua CA yang dipercaya oleh sistem dapat menetapkan kumpulan CA-nya sendiri yang telah dikurangi untuk dipercaya. Tindakan ini akan melindungi aplikasi dari sertifikat palsu dikeluarkan oleh CA lainnya.

Konfigurasi yang membatasi kumpulan CA tepercaya mirip dengan memercayai CA khusus untuk domain tertentu, selain beberapa CA disediakan dalam resource.

res/xml/network_security_config.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <domain-config>
            <domain includeSubdomains="true">secure.example.com</domain>
            <domain includeSubdomains="true">cdn.example.com</domain>
            <trust-anchors>
                <certificates src="@raw/trusted_roots"/>
            </trust-anchors>
        </domain-config>
    </network-security-config>
    

Tambahkan CA tepercaya (dalam format PEM atau DER) ke res/raw/trusted_roots. Perhatikan, jika menggunakan format PEM, file hanya boleh berisi data PEM dan tidak ada teks tambahan. Anda juga dapat memberikan lebih dari satu elemen <certificates>.

Memercayai CA tambahan

Sebuah aplikasi mungkin perlu memercayai CA tambahan yang tidak dipercaya oleh sistem. Hal ini bisa disebabkan sistem yang belum menyertakan CA atau CA tidak memenuhi persyaratan untuk dimasukkan ke dalam sistem Android. Aplikasi bisa melakukannya dengan menetapkan beberapa sumber sertifikat untuk konfigurasi.

res/xml/network_security_config.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <base-config>
            <trust-anchors>
                <certificates src="@raw/extracas"/>
                <certificates src="system"/>
            </trust-anchors>
        </base-config>
    </network-security-config>
    

Mengonfigurasikan CA untuk proses debug

Saat melakukan debug aplikasi yang terhubung melalui HTTPS, Anda mungkin perlu menghubungkan ke server pengembangan lokal, yang tidak memiliki sertifikat SSL untuk server produksi Anda. Untuk mendukung hal ini tanpa modifikasi kode aplikasi Anda, Anda dapat menentukan CA khusus debug, yang hanya dipercaya saat android:debuggable adalah true, dengan menggunakan debug-overrides. Biasanya IDE dan fitur build menyetel flag ini secara otomatis untuk build non-rilis.

Ini lebih aman daripada kode kondisional biasa karena, sebagai tindakan pencegahan keamanan, app store tidak menerima aplikasi yang ditandai sebagai bisa di-debug.

res/xml/network_security_config.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <debug-overrides>
            <trust-anchors>
                <certificates src="@raw/debug_cas"/>
            </trust-anchors>
        </debug-overrides>
    </network-security-config>
    

Memilih tidak menggunakan traffic cleartext

Catatan: Panduan dalam bagian ini hanya berlaku untuk aplikasi yang menargetkan Android 8.1 (API level 27) atau versi yang lebih rendah. Dimulai dengan Android 9 (API level 28), dukungan cleartext dinonaktifkan secara default.

Aplikasi yang ingin terhubung ke tujuan dengan hanya menggunakan sambungan aman dapat memilih tidak menggunakan dukungan cleartext (menggunakan protokol HTTP tidak terenkripsi sebagai ganti HTTPS) ke tujuan tersebut. Opsi ini akan membantu mencegah regresi yang tidak disengaja dalam aplikasi karena perubahan dalam URL yang disediakan oleh sumber-sumber eksternal seperti server backend. Lihat NetworkSecurityPolicy.isCleartextTrafficPermitted() untuk mengetahui detail selengkapnya.

Misalnya, aplikasi mungkin ingin memastikan semua sambungan ke secure.example.com selalu dilakukan melalui HTTPS untuk melindungi traffic sensitif dari jaringan yang berbahaya.

res/xml/network_security_config.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <domain-config cleartextTrafficPermitted="false">
            <domain includeSubdomains="true">secure.example.com</domain>
        </domain-config>
    </network-security-config>
    

Pemasangan pin pada sertifikat

Biasanya, aplikasi memercayai semua CA yang telah diinstal. Jika salah satu dari CA ini mengeluarkan sertifikat palsu, aplikasi akan berisiko terkena serangan man-in-the-middle. Beberapa aplikasi memilih untuk membatasi kumpulan sertifikat yang mereka terima, baik dengan membatasi kumpulan CA yang mereka percayai atau dengan memasang pin pada sertifikat.

Pemasangan pin pada sertifikat dilakukan dengan memberikan kumpulan sertifikat dengan hash kunci publik (SubjectPublicKeyInfo pada sertifikat X.509). Rantai sertifikat nantinya hanya berlaku jika rantai sertifikat berisi setidaknya salah satu dari kunci publik yang dipasangi pin.

Perlu diingat bahwa saat menggunakan pemasangan pin pada sertifikat, Anda harus selalu menyertakan kunci cadangan sehingga jika Anda terpaksa beralih ke kunci baru atau mengubah CA (saat memasang pin pada sertifikat CA atau perantara CA tersebut), konektivitas aplikasi Anda tidak terpengaruh. Jika tidak, Anda harus menerapkan update ke aplikasi tersebut untuk memulihkan konektivitas.

Selain itu, Anda juga dapat menyetel waktu habis masa berlaku untuk pin setelah pemasangan pin tidak dilakukan. Hal ini membantu mencegah masalah konektivitas dalam aplikasi yang belum diupdate. Akan tetapi, menyetel waktu habis masa berlaku pada pin mungkin akan membuat pemasangan pin bisa diabaikan.

res/xml/network_security_config.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <domain-config>
            <domain includeSubdomains="true">example.com</domain>
            <pin-set expiration="2018-01-01">
                <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
                <!-- backup pin -->
                <pin digest="SHA-256">fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=</pin>
            </pin-set>
        </domain-config>
    </network-security-config>
    

Perilaku Pewarisan Konfigurasi

Nilai yang tidak disetel dalam konfigurasi tertentu akan diwariskan. Perilaku ini mengizinkan konfigurasi yang lebih kompleks selagi menjaga file konfigurasi tetap terbaca.

Jika nilai tidak disetel dalam entri tertentu, nilai dari entri yang lebih umum akan digunakan. Sebagai contoh, nilai yang tidak disetel dalam domain-config diambil dari domain-config induk (jika bertingkat), atau dari base-config (jika tidak bertingkat). Nilai-nilai yang tidak disetel di base-config menggunakan nilai default platform.

Misalnya, pertimbangkan jika semua sambungan ke subdomain example.com harus menggunakan kumpulan CA khusus. Selain itu, traffic cleartext ke domain ini diizinkan, kecuali saat terhubung ke secure.example.com. Dengan membuat konfigurasi bertingkat untuk secure.example.com di dalam konfigurasi untuk example.com, trust-anchors tidak perlu diduplikasi.

res/xml/network_security_config.xml:

    <?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 cleartextTrafficPermitted="false">
                <domain includeSubdomains="true">secure.example.com</domain>
            </domain-config>
        </domain-config>
    </network-security-config>
    

Format file konfigurasi

Fitur Konfigurasi Keamanan Jaringan menggunakan format file XML. Struktur keseluruhan file ditampilkan dalam contoh kode berikut:

    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <base-config>
            <trust-anchors>
                <certificates src="..."/>
                ...
            </trust-anchors>
        </base-config>

        <domain-config>
            <domain>android.com</domain>
            ...
            <trust-anchors>
                <certificates src="..."/>
                ...
            </trust-anchors>
            <pin-set>
                <pin digest="...">...</pin>
                ...
            </pin-set>
        </domain-config>
        ...
        <debug-overrides>
            <trust-anchors>
                <certificates src="..."/>
                ...
            </trust-anchors>
        </debug-overrides>
    </network-security-config>
    

Bagian berikut menjelaskan sintaks dan detail lainnya dari format file tersebut.

<network-security-config>

bisa berisi:
0 atau 1 dari <base-config>
Sejumlah <domain-config>
0 atau 1 dari <debug-overrides>

<base-config>

sintaks:
    <base-config cleartextTrafficPermitted=["true" | "false"]>
        ...
    </base-config>
    
bisa berisi:
<trust-anchors>
deskripsi:
Konfigurasi default digunakan oleh semua sambungan yang tujuannya tidak tercakup oleh domain-config.

Nilai yang tidak disetel akan menggunakan nilai default platform.

Konfigurasi default untuk aplikasi yang menargetkan Android 7.0 (API level 24) dan versi yang lebih tinggi adalah seperti berikut:

    <base-config cleartextTrafficPermitted="false">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
    

Konfigurasi default untuk aplikasi yang menargetkan Android 7.0 (API level 24) hingga Android 8.1 (API level 27) adalah sebagai berikut:

    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
    

Konfigurasi default untuk aplikasi yang menargetkan Android 6.0 (API level 23) dan versi yang lebih rendah adalah seperti berikut:

    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
            <certificates src="user" />
        </trust-anchors>
    </base-config>
    

<domain-config>

sintaks:
<domain-config cleartextTrafficPermitted=["true" | "false"]>
        ...
    </domain-config>
Bisa Berisi:
1 <domain> atau lebih
0 atau 1 <trust-anchors>
0 atau 1 <pin-set>
Sejumlah <domain-config> bertingkat
Deskripsi
Konfigurasi yang digunakan untuk menyambungkan ke tujuan tertentu, seperti ditetapkan oleh elemen domain.

Jika beberapa elemen domain-config mencakup suatu tujuan, konfigurasi dengan aturan domain paling spesifik (terpanjang) yang cocok akan digunakan.

<domain>

sintaks:
    <domain includeSubdomains=["true" | "false"]>example.com</domain>
    
Atribut:
includeSubdomains
Jika "true" , aturan domain ini cocok dengan domain dan semua subdomain, termasuk subdomain dari subdomain. Jika tidak, aturan hanya berlaku untuk kecocokan yang sama persis.
Deskripsi:

<debug-overrides>

sintaks:
    <debug-overrides>
        ...
    </debug-overrides>
    
Bisa Berisi:
0 atau 1 <trust-anchors>
Deskripsi:
Penggantian diterapkan ketika android:debuggable adalah "true", yang biasanya merupakan kasus untuk build non-rilis yang dihasilkan oleh IDE dan fitur build. Anchor kepercayaan yang ditetapkan dalam debug-overrides akan ditambahkan ke semua konfigurasi lainnya, dan pemasangan pin pada sertifikat tidak akan dilakukan jika rantai sertifikat server menggunakan salah satu dari anchor kepercayaan khusus debug ini. Apabila android:debuggable adalah "false", bagian ini akan sepenuhnya diabaikan.

<trust-anchors>

sintaks:
    <trust-anchors>
    ...
    </trust-anchors>
    
Bisa Berisi:
Sejumlah <certificates>
Deskripsi:
Kumpulan anchor kepercayaan untuk sambungan aman.

<certificates>

sintaks:
<certificates src=["system" | "user" | "raw resource"]
                  overridePins=["true" | "false"] />
    
deskripsi:
Kumpulan sertifikat X.509 untuk elemen trust-anchors.
atribut:
src
Sumber sertifikat CA. Setiap sertifikat bisa menjadi salah satu hal berikut:
  • ID resource mentah yang menunjuk ke file berisi sertifikat X.509. Sertifikat harus dienkode dalam format DER atau PEM. Pada sertifikat PEM, file tidak boleh berisi data non-PEM tambahan seperti komentar.
  • "system" untuk sertifikat CA sistem yang telah diinstal sebelumnya
  • "user" untuk sertifikat CA yang ditambahkan pengguna
overridePins

Menetapkan apakah CA dari sumber ini akan mengabaikan pemasangan pin pada sertifikat. Jika "true", penyematan tidak dilakukan pada rantai sertifikat yang ditandatangani oleh salah satu CA dari sumber ini. Hal ini bisa berguna untuk melakukan debug CA atau untuk menguji serangan man-in-the-middle pada traffic aman aplikasi Anda.

Default-nya adalah "false", kecuali ditentukan dalam elemen debug-overrides, dalam hal ini default-nya adalah "true".

<pin-set>

sintaks:
    <pin-set expiration="date">
    ...
    </pin-set>
    
Bisa Berisi:
Sejumlah <pin>
Deskripsi:
Kumpulan pin kunci publik. Agar sambungan aman bisa dipercaya, salah satu kunci publik dalam rantai kepercayaan harus berada dalam kumpulan pin. Lihat <pin> untuk format pin.
Atribut:
expiration
Tanggal, dalam format yyyy-MM-dd, di mana masa berlaku pin berakhir, sehingga akan menonaktifkan pemasangan pin. Jika atribut tidak disetel, pin akan tetap berlaku.

Masa berlaku membantu mencegah masalah konektivitas di aplikasi yang tidak melakukan update untuk kumpulan pin mereka, seperti ketika pengguna menonaktifkan update aplikasi.

<pin>

sintaks:
    <pin digest=["SHA-256"]>base64 encoded digest of X.509
        SubjectPublicKeyInfo (SPKI)</pin>
    
Atribut:
digest
Algoritme ringkasan yang digunakan untuk menghasilkan pin. Saat ini, hanya "SHA-256" yang didukung.

Referensi lainnya

Untuk mengetahui informasi selengkapnya mengenai Konfigurasi Keamanan Jaringan, lihat referensi berikut.

Codelab