Ketersediaan Trusted Execution Environment (TEE) dalam system on a chip (SoC) memberikan peluang bagi perangkat Android untuk menyediakan layanan keamanan kuat yang didukung hardware ke OS Android, layanan platform, dan bahkan ke aplikasi pihak ketiga (dalam bentuk ekstensi khusus Android untuk Java Cryptography Architecture standar, lihat KeyGenParameterSpec
).
Glosarium
Berikut adalah ringkasan singkat komponen Keystore dan hubungannya.
AndroidKeyStore
- Android Framework API dan komponen yang digunakan
oleh aplikasi untuk mengakses fungsi Keystore. Ini adalah implementasi
API Java Cryptography Architecture standar, tetapi juga menambahkan ekstensi
khusus Android dan terdiri dari kode Java yang berjalan di ruang
proses aplikasi itu sendiri.
AndroidKeyStore
memenuhi permintaan aplikasi untuk perilaku Keystore dengan meneruskannya ke daemon keystore. - daemon keystore
- Daemon sistem Android yang menyediakan akses ke semua fungsi Keystore melalui Binder API. Daemon ini bertanggung jawab untuk menyimpan keyblob yang dibuat oleh implementasi KeyMint (atau Keymaster) yang mendasarinya, yang berisi materi kunci rahasia, dienkripsi sehingga Keystore dapat menyimpannya, tetapi tidak dapat menggunakan atau mengungkapkannya.
- Layanan KeyMint HAL
- Server AIDL yang menerapkan
HAL
IKeyMintDevice
, yang menyediakan akses ke TA KeyMint yang mendasarinya. - Aplikasi tepercaya (TA) KeyMint
- Software yang berjalan dalam konteks yang aman, paling sering di TrustZone pada ARM SoC, yang menyediakan semua operasi kriptografi yang aman. Aplikasi ini memiliki akses ke materi kunci mentah, dan memvalidasi semua kondisi kontrol akses pada kunci sebelum mengizinkan penggunaannya.
LockSettingsService
- Komponen sistem Android yang bertanggung jawab atas autentikasi pengguna, baik sandi maupun
sidik jari. Fitur ini bukan bagian dari Keystore, tetapi relevan karena Keystore mendukung konsep
kunci terikat autentikasi: kunci yang hanya dapat digunakan jika pengguna telah diautentikasi.
LockSettingsService
berinteraksi dengan TA Gatekeeper dan TA Sidik Jari untuk mendapatkan token autentikasi, yang diberikannya ke daemon keystore, dan yang digunakan oleh TA KeyMint. - TA Gatekeeper
- Komponen yang berjalan di lingkungan aman yang bertanggung jawab untuk mengautentikasi sandi pengguna dan membuat token autentikasi yang digunakan untuk membuktikan kepada TA KeyMint bahwa autentikasi telah dilakukan untuk pengguna tertentu pada waktu tertentu.
- TA Sidik Jari
- Komponen yang berjalan di lingkungan aman yang bertanggung jawab untuk mengautentikasi sidik jari pengguna dan membuat token autentikasi yang digunakan untuk membuktikan kepada TA KeyMint bahwa autentikasi telah dilakukan untuk pengguna tertentu pada waktu tertentu.
Arsitektur
Android Keystore API dan KeyMint HAL yang mendasarinya menyediakan serangkaian primitif kriptografi dasar tetapi memadai untuk memungkinkan penerapan protokol menggunakan kunci yang didukung hardware dan dikontrol aksesnya.
HAL KeyMint adalah layanan yang disediakan OEM yang digunakan oleh layanan Keystore untuk menyediakan layanan kriptografi yang didukung hardware. Untuk menjaga keamanan materi kunci pribadi, implementasi HAL tidak melakukan operasi sensitif apa pun di ruang pengguna, atau bahkan di ruang kernel. Sebagai gantinya, layanan KeyMint HAL yang berjalan di Android mendelegasikan operasi sensitif ke TA yang berjalan di beberapa jenis lingkungan yang aman, biasanya dengan menyusun dan mengurai permintaan dalam beberapa format wire yang ditentukan implementasinya.
Arsitektur yang dihasilkan akan terlihat seperti ini:

Gambar 1. Akses ke KeyMint.
API HAL KeyMint memiliki level rendah, digunakan oleh komponen internal platform, dan tidak diekspos ke developer aplikasi. Java API tingkat tinggi yang tersedia untuk aplikasi dijelaskan di situs Android Developer.
Access control
Android Keystore menyediakan komponen pusat untuk penyimpanan dan penggunaan kunci kriptografi yang didukung hardware, baik untuk aplikasi maupun untuk komponen sistem lainnya. Oleh karena itu, akses ke setiap kunci biasanya dibatasi untuk aplikasi atau komponen sistem yang membuat kunci tersebut.
Domain keystore
Untuk mendukung kontrol akses ini, kunci diidentifikasi ke Keystore dengan deskriptor kunci. Deskriptor kunci ini menunjukkan domain yang dimiliki deskriptor, bersama dengan identitas dalam domain tersebut.
Aplikasi Android mengakses Keystore menggunakan Java Cryptography Architecture standar, yang mengidentifikasi kunci dengan alias string. Metode
identifikasi ini dipetakan ke domain APP
Keystore secara internal;
UID pemanggil juga disertakan untuk membedakan kunci dari aplikasi
yang berbeda, sehingga mencegah satu aplikasi mengakses kunci aplikasi lain.
Secara internal, kode framework juga menerima ID kuncinumerik unik setelah kunci dimuat. ID numerik ini digunakan sebagai ID
untuk deskriptor utama dalam domain KEY_ID
. Namun, kontrol akses tetap dilakukan: meskipun satu aplikasi menemukan ID kunci untuk kunci aplikasi lain, aplikasi tersebut tidak dapat menggunakannya dalam keadaan normal.
Namun, aplikasi dapat memberikan penggunaan kunci ke aplikasi lain
(seperti yang diidentifikasi oleh UID). Operasi pemberian ini menampilkan ID pemberian unik,
yang digunakan sebagai ID untuk deskriptor kunci dalam
domain GRANT
. Sekali lagi, kontrol akses tetap dilakukan: meskipun
aplikasi pihak ketiga menemukan ID pemberian untuk kunci penerima, aplikasi tersebut tidak dapat menggunakannya.
Keystore juga mendukung dua domain lain untuk deskriptor kunci, yang digunakan untuk komponen sistem lain dan tidak tersedia untuk kunci yang dibuat aplikasi:
- Domain
BLOB
menunjukkan bahwa tidak ada ID untuk kunci dalam deskriptor kunci; sebagai gantinya, deskriptor kunci menyimpan keyblob itu sendiri dan klien menangani penyimpanan keyblob. Ini digunakan oleh klien (misalnya,vold
) yang perlu mengakses Keystore sebelum partisi data di-mount. - Domain
SELINUX
memungkinkan komponen sistem berbagi kunci, dengan akses yang diatur oleh ID numerik yang sesuai dengan label SELinux (lihat kebijakan SELinux untuk keystore_key).
Kebijakan SELinux untuk keystore_key
Nilai ID yang digunakan untuk deskriptor kunci Domain::SELINUX
dikonfigurasi dalam file kebijakan SELinux keystore2_key_context
.
Setiap baris dalam file ini memetakan numerik ke label SELinux, misalnya:
# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and # Settings to share Keystore keys. 102 u:object_r:wifi_key:s0
Komponen yang memerlukan akses ke kunci dengan ID 102 di
domain SELINUX
harus memiliki kebijakan SELinux yang sesuai. Misalnya, untuk mengizinkan wpa_supplicant
mendapatkan dan menggunakan kunci ini, tambahkan baris berikut ke hal_wifi_supplicant.te
:
allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };
ID numerik untuk kunci Domain::SELINUX
dibagi
ke dalam rentang untuk mendukung partisi yang berbeda tanpa konflik:
Partisi | Rentang | File konfigurasi |
---|---|---|
Sistem | 0 ... 9.999 | /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts
|
Sistem yang Diperluas | 10.000 ... 19.999 | /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts
|
Produk | 20.000 ... 29.999 | /product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts
|
Vendor | 30.000 ... 39.999 | /vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts
|
Nilai spesifik berikut telah ditentukan untuk partisi sistem:
ID Ruangnama | Label SEPolicy | UID | Deskripsi |
---|---|---|---|
0 | su_key |
T/A | Kunci super user. Hanya digunakan untuk pengujian pada build userdebug dan eng. Tidak relevan pada build pengguna. |
1 | shell_key |
T/A | Namespace tersedia untuk shell. Sebagian besar digunakan untuk pengujian, tetapi juga dapat digunakan pada build pengguna dari command line. |
100 | vold_key |
T/A | Ditujukan untuk digunakan oleh vold. |
101 | odsign_key |
T/A | Digunakan oleh daemon penandatanganan di perangkat. |
102 | wifi_key |
AID_WIFI(1010) |
Digunakan oleh subsistem Wi-Fi Android, termasuk wpa_supplicant . |
103 | locksettings_key |
T/A | Digunakan oleh LockSettingsService |
120 | resume_on_reboot_key |
AID_SYSTEM(1000) |
Digunakan oleh server sistem Android untuk mendukung melanjutkan setelah memulai ulang. |
Vektor akses
Keystore memungkinkan kontrol atas operasi yang dapat dilakukan pada kunci, selain mengontrol akses keseluruhan ke kunci. Izin keystore2_key
dijelaskan dalam
file KeyPermission.aidl
.
Izin sistem
Selain kontrol akses per kunci yang dijelaskan dalam Kebijakan SELinux untuk keystore_key, tabel berikut menjelaskan izin SELinux lainnya yang diperlukan untuk melakukan berbagai operasi sistem dan pemeliharaan:
Izin | Arti |
---|---|
add_auth
|
Diperlukan untuk menambahkan token autentikasi ke Keystore; digunakan oleh penyedia autentikasi seperti Gatekeeper atau BiometricManager . |
clear_ns
|
Diperlukan untuk menghapus semua kunci dalam namespace tertentu; digunakan sebagai operasi pemeliharaan saat aplikasi di-uninstal. |
list
|
Diperlukan oleh sistem untuk menghitung kunci berdasarkan berbagai properti, seperti kepemilikan atau apakah kunci tersebut terikat autentikasi. Izin ini tidak diperlukan oleh pemanggil yang
meng-enumerasi namespace mereka sendiri (dicakup oleh
izin get_info ). |
lock
|
Diperlukan untuk memberi tahu keystore bahwa perangkat dikunci, yang pada gilirannya akan mengeluarkan kunci super untuk memastikan kunci yang terikat autentikasi tidak tersedia. |
unlock
|
Diperlukan untuk memberi tahu keystore bahwa perangkat telah dibuka kuncinya, memulihkan akses ke kunci super yang melindungi kunci terikat autentikasi. |
reset
|
Diperlukan untuk mereset Keystore ke setelan default pabrik, menghapus semua kunci yang tidak penting untuk fungsi OS Android. |
Histori
Di Android 5 dan yang lebih rendah, Android memiliki API layanan kriptografi sederhana yang didukung hardware, yang disediakan oleh Keymaster hardware abstraction layer (HAL) versi 0.2 dan 0.3. Keystore menyediakan operasi penandatanganan dan verifikasi digital, serta pembuatan dan impor pasangan kunci penandatanganan asimetris. Hal ini sudah diterapkan di banyak perangkat, tetapi ada banyak tujuan keamanan yang tidak dapat dicapai dengan mudah hanya dengan API tanda tangan. Android 6.0 memperluas Keystore API untuk menyediakan berbagai kemampuan yang lebih luas.
Android 6.0
Di Android 6.0, Keymaster 1.0 menambahkan primitif kriptografi simetris, AES dan HMAC, serta sistem kontrol akses untuk kunci yang didukung hardware. Kontrol akses ditentukan selama pembuatan kunci dan diterapkan selama masa aktif kunci. Kunci dapat dibatasi agar hanya dapat digunakan setelah pengguna diautentikasi, dan hanya untuk tujuan tertentu atau dengan parameter kriptografi tertentu.
Selain memperluas rentang primitif kriptografi, Keystore di Android 6.0 menambahkan hal berikut:
- Skema kontrol penggunaan untuk membatasi penggunaan kunci, guna mengurangi risiko pelanggaran keamanan akibat penyalahgunaan kunci
- Skema kontrol akses untuk mengaktifkan pembatasan kunci bagi pengguna, klien, dan rentang waktu tertentu
Android 7.0
Di Android 7.0, Keymaster 2 menambahkan dukungan untuk pengesahan kunci dan pengikatan versi.
Pengesahan kunci menyediakan sertifikat kunci publik yang berisi deskripsi mendetail tentang kunci dan kontrol aksesnya, untuk membuat keberadaan kunci di hardware yang aman dan konfigurasinya dapat diverifikasi dari jarak jauh.
Pengikatan versi mengikat kunci ke versi sistem operasi dan tingkat patch. Hal ini memastikan bahwa penyerang yang menemukan kelemahan dalam sistem versi lama atau software TEE tidak dapat melakukan roll back perangkat ke versi yang rentan dan menggunakan kunci yang dibuat dengan versi yang lebih baru. Selain itu, saat kunci dengan versi dan tingkat patch tertentu digunakan di perangkat yang telah diupgrade ke versi atau tingkat patch yang lebih baru, kunci tersebut akan diupgrade sebelum dapat digunakan, dan versi kunci sebelumnya akan dibatalkan. Saat perangkat diupgrade, kunci akan di-ratchet bersama dengan perangkat, tetapi setiap pengembalian perangkat ke rilis sebelumnya akan menyebabkan kunci tidak dapat digunakan.
Android 8.0
Di Android 8.0, Keymaster 3 bertransisi dari HAL struktur C gaya lama ke antarmuka HAL C++ yang dihasilkan dari definisi dalam hardware interface definition language (HIDL) baru. Sebagai bagian dari perubahan ini, banyak jenis argumen yang berubah, meskipun jenis dan metode memiliki korespondensi satu-ke-satu dengan jenis lama dan metode struct HAL.
Selain revisi antarmuka ini, Android 8.0 memperluas fitur pengesahan Keymaster 2 untuk mendukung pengesahan ID. Pengesahan ID menyediakan mekanisme terbatas dan opsional untuk mengesahkan ID hardware secara kuat, seperti nomor seri perangkat, nama produk, dan ID ponsel (IMEI atau MEID). Untuk menerapkan penambahan ini, Android 8.0 mengubah skema pengesahan ASN.1 untuk menambahkan pengesahan ID. Implementasi Keymaster harus menemukan cara yang aman untuk mengambil item data yang relevan, serta menentukan mekanisme untuk menonaktifkan fitur secara aman dan permanen.
Android 9
Di Android 9, update mencakup:
- Update ke Keymaster 4
- Dukungan untuk Elemen Keamanan tersemat
- Dukungan untuk impor kunci yang aman
- Dukungan untuk enkripsi 3DES
- Perubahan pada pengikatan versi sehingga
boot.img
dansystem.img
memiliki versi yang ditetapkan secara terpisah untuk memungkinkan update independen
Android 10
Android 10 memperkenalkan Keymaster HAL versi 4.1, yang menambahkan:
- Dukungan untuk kunci yang hanya dapat digunakan saat perangkat tidak terkunci
- Dukungan untuk kunci yang hanya dapat digunakan pada tahap booting awal
- Dukungan opsional untuk kunci penyimpanan yang dienkapsulasi hardware
- Dukungan opsional untuk pengesahan unik per perangkat di StrongBox
Android 12
Android 12 memperkenalkan KeyMint HAL baru, yang menggantikan Keymaster HAL tetapi menyediakan fungsi yang serupa. Selain semua fitur di atas, HAL KeyMint juga mencakup:
- Dukungan untuk perjanjian kunci ECDH
- Dukungan untuk kunci pengesahan yang ditentukan pengguna
- Dukungan untuk kunci dengan jumlah penggunaan terbatas
Android 12 juga menyertakan versi baru daemon sistem keystore,
yang ditulis ulang di Rust dan dikenal sebagai keystore2
Android 13
Android 13 menambahkan HAL KeyMint v2, yang menambahkan dukungan untuk Curve25519 untuk penandatanganan dan perjanjian kunci.