Konfigurasi keamanan jaringan

Fitur Konfigurasi Keamanan Jaringan memungkinkan Anda menyesuaikan setelan keamanan jaringan aplikasi dalam file konfigurasi deklaratif yang aman tanpa mengubah kode aplikasi. Setelan ini dapat dikonfigurasi untuk domain dan aplikasi tertentu. Kemampuan utama fitur ini adalah:

  • Trust anchor kustom: Menyesuaikan Certificate Authority (CA) mana yang dipercaya untuk koneksi aman suatu aplikasi. Misalnya, memercayai sertifikat tertentu yang ditandatangani sendiri atau membatasi kumpulan CA publik yang dipercaya aplikasi.
  • Penggantian khusus debug: Melakukan debug koneksi aman tanpa masalah di aplikasi tanpa menambah risiko di basis yang diinstal.
  • Penonaktifan traffic cleartext: Melindungi aplikasi dari penggunaan traffic cleartext (tidak dienkripsi) yang tidak disengaja.
  • Pemasangan pin di sertifikat: Membatasi koneksi aman aplikasi ke sertifikat tertentu.

Menambahkan file Konfigurasi Keamanan Jaringan

Fitur Konfigurasi Keamanan Jaringan menggunakan file XML tempat Anda menentukan setelan untuk aplikasi. Anda harus menyertakan entri dalam manifes aplikasi untuk mengarah ke file ini. Cuplikan kode berikut dari suatu 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

Anda mungkin ingin aplikasi Anda memercayai kumpulan CA kustom, bukan default platform. Alasan paling umum untuk hal ini adalah:

  • Menghubungkan ke host dengan CA kustom, seperti CA yang ditandatangani sendiri atau diterbitkan 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, koneksi aman (menggunakan protokol seperti TLS dan HTTPS) dari semua aplikasi memercayai CA sistem yang telah diinstal sebelumnya, dan aplikasi yang menargetkan Android 6.0 (level API 23) dan yang lebih rendah juga memercayai penyimpanan CA yang ditambahkan oleh pengguna secara default. Anda dapat menyesuaikan koneksi aplikasi menggunakan base-config (untuk penyesuaian di seluruh aplikasi) atau domain-config (untuk penyesuaian per domain).

Mengonfigurasikan CA kustom

Anda mungkin ingin menghubungkan ke host yang menggunakan sertifikat SSL yang ditandatangani sendiri atau ke host yang sertifikat SSL-nya diterbitkan oleh CA non-publik yang Anda percaya, seperti CA internal perusahaan Anda. Cuplikan kode berikut menunjukkan cara mengonfigurasi aplikasi Anda untuk CA kustom di 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

Jika tidak ingin aplikasi Anda memercayai semua CA yang dipercaya oleh sistem, Anda dapat menentukan pengurangan kumpulan CA yang akan dipercaya. Tindakan ini akan melindungi aplikasi dari sertifikat palsu yang diterbitkan oleh CA lainnya.

Konfigurasi yang membatasi kumpulan CA tepercaya mirip dengan memercayai CA kustom untuk domain tertentu, kecuali bahwa beberapa CA disediakan dalam resource. Cuplikan kode berikut menunjukkan cara membatasi kumpulan CA tepercaya aplikasi Anda di 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 bahwa jika Anda menggunakan format PEM, file hanya boleh berisi data PEM dan tidak boleh ada teks tambahan. Anda juga dapat memberikan lebih dari satu elemen <certificates>.

Memercayai CA tambahan

Anda mungkin ingin aplikasi Anda memercayai CA tambahan yang tidak dipercaya oleh sistem, misalnya jika sistem belum menyertakan CA, atau CA tidak memenuhi persyaratan untuk disertakan dalam sistem Android. Anda dapat menentukan beberapa sumber sertifikat untuk konfigurasi di res/xml/network_security_config.xml menggunakan kode seperti cuplikan berikut.

<?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 men-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 mengubah kode aplikasi, Anda dapat menentukan CA khusus debug, yang hanya dipercaya saat android:debuggable adalah true, dengan menggunakan debug-overrides. Biasanya, IDE dan alat build otomatis menetapkan flag ini untuk build non-rilis.

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

Cuplikan di bawah ini menunjukkan cara menentukan CA khusus debug dalam 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>

Penonaktifan traffic cleartext

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

Jika ingin aplikasi Anda terhubung ke tujuan hanya dengan menggunakan koneksi aman, Anda dapat memilih untuk tidak mendukung cleartext (menggunakan protokol HTTP yang tidak terenkripsi, bukan HTTPS) ke tujuan tersebut. Opsi ini akan membantu mencegah regresi tidak disengaja dalam aplikasi karena perubahan dalam URL yang disediakan oleh sumber eksternal seperti server backend. Lihat NetworkSecurityPolicy.isCleartextTrafficPermitted() untuk mengetahui detail selengkapnya.

Misalnya, Anda mungkin ingin aplikasi memastikan bahwa koneksi ke secure.example.com selalu dilakukan melalui HTTPS untuk melindungi traffic sensitif dari jaringan yang tidak aman.

Cuplikan di bawah menunjukkan cara memilih untuk tidak menggunakan cleartext di 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 di sertifikat

Biasanya, aplikasi memercayai semua CA yang telah diinstal. Jika salah satu dari CA ini menerbitkan sertifikat palsu, aplikasi akan berisiko menghadapi penyerang di jalur. Beberapa aplikasi memilih untuk membatasi kumpulan sertifikat yang mereka terima, baik dengan membatasi kumpulan CA yang mereka percayai maupun dengan memasang pin di sertifikat.

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

Perlu diingat bahwa saat menggunakan pemasangan pin di sertifikat, Anda harus selalu menyertakan kunci cadangan sehingga jika Anda terpaksa beralih ke kunci baru atau mengubah CA (saat memasang pin di 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. Namun, menyetel waktu habis masa berlaku pada pin dapat memungkinkan penyerang mengabaikan sertifikat yang dipasangi pin.

Cuplikan di bawah menunjukkan cara memasang pin di sertifikat di 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 memungkinkan konfigurasi yang lebih kompleks sekaligus menjaga file konfigurasi tetap terbaca.

Contohnya, nilai yang tidak ditetapkan dalam domain-config akan diambil dari domain-config induk, jika bertingkat, atau dari base-config, jika tidak bertingkat. Nilai-nilai yang tidak ditetapkan dalam base-config akan menggunakan nilai default platform.

Misalnya, pertimbangkan kasus ketika semua koneksi ke subdomain example.com harus menggunakan kumpulan CA kustom. 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.

Cuplikan di bawah ini menunjukkan tampilan tingkat tersebut di 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 sintaksis dan detail lainnya dari format file tersebut.

<network-security-config>

dapat berisi:
0 atau 1 dari <base-config>
Angka berapa pun dari <domain-config>
0 atau 1 dari <debug-overrides>

<base-config>

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

Nilai yang tidak disetel akan menggunakan nilai default platform.

Konfigurasi default untuk aplikasi yang menargetkan Android 9 (level API 28) 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 (level API 24) hingga Android 8.1 (level API 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 (level API 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>

sintaksis:
<domain-config cleartextTrafficPermitted=["true" | "false"]>
    ...
</domain-config>
dapat berisi:
1 atau lebih <domain>
0 atau 1 <trust-anchors>
0 atau 1 <pin-set>
Angka berapa pun dari <domain-config> bertingkat
deskripsi:
Konfigurasi yang digunakan untuk koneksi ke tujuan tertentu, seperti yang ditetapkan oleh elemen domain.

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

<domain>

sintaksis:
<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.

<debug-overrides>

sintaksis:
<debug-overrides>
    ...
</debug-overrides>
dapat berisi:
0 atau 1 <trust-anchors>
deskripsi:
Penggantian diterapkan ketika android:debuggable bernilai "true", yang biasanya terjadi pada build non-rilis yang dihasilkan oleh IDE dan alat build. Trust anchor yang ditetapkan dalam debug-overrides akan ditambahkan ke semua konfigurasi lainnya, dan pemasangan pin di sertifikat tidak akan dilakukan jika rantai sertifikat server menggunakan salah satu dari trust anchor khusus debug ini. Jika android:debuggable bernilai "false", bagian ini akan sepenuhnya diabaikan.

<trust-anchors>

sintaksis:
<trust-anchors>
...
</trust-anchors>
dapat berisi:
Angka berapa pun dari <certificates>
deskripsi:
Kumpulan trust anchor untuk koneksi aman.

<certificates>

sintaksis:
<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 dapat menjadi salah satu hal berikut:
  • ID resource mentah yang menunjuk ke file berisi sertifikat X.509. Sertifikat harus dienkode dalam format DER atau PEM. Di 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 sertifikat. Jika "true", pemasangan pin tidak dilakukan di rantai sertifikat yang ditandatangani oleh salah satu CA dari sumber ini. Pemasangan pin ini dapat bermanfaat untuk men-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>

sintaksis:
<pin-set expiration="date">
...
</pin-set>
dapat berisi:
Angka berapa pun dari <pin>
deskripsi:
Kumpulan pin kunci publik. Agar koneksi aman dapat dipercaya, salah satu kunci publik dalam rantai kepercayaan harus berada dalam kumpulan pin. Lihat <pin> untuk mengetahui format pin.
atribut:
expiration
Tanggal, dalam format yyyy-MM-dd, ketika 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 pinnya, misalnya ketika pengguna menonaktifkan update aplikasi.

<pin>

sintaksis:
<pin digest=["SHA-256"]>base64 encoded digest of X.509
    SubjectPublicKeyInfo (SPKI)</pin>
atribut:
digest
Algoritma digest 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