Halaman ini berisi informasi tentang fitur kriptografi Android Keystore, seperti yang disediakan oleh implementasi KeyMint (atau Keymaster) yang mendasarinya.
Primitif kriptografi
Keystore menyediakan kategori operasi berikut:
- Pembuatan kunci, yang menghasilkan materi kunci pribadi atau rahasia yang
hanya dapat diakses oleh lingkungan aman. Klien dapat membuat kunci dengan cara
berikut:
- Pembuatan kunci baru
- Impor materi kunci yang tidak dienkripsi
- Impor materi kunci terenkripsi
- Pengesahan kunci: Pembuatan kunci asimetris menghasilkan sertifikat yang menyimpan bagian kunci publik dari pasangan kunci. Sertifikat ini secara opsional juga menyimpan informasi tentang metadata untuk kunci dan status perangkat, yang semuanya ditandatangani oleh rantai kunci kembali ke root tepercaya.
- Operasi kriptografis:
- Enkripsi dan dekripsi simetris (AES, 3DES)
- Dekripsi asimetris (RSA)
- Penandatanganan asimetris (ECDSA, RSA)
- Penandatanganan dan verifikasi simetris (HMAC)
- Perjanjian kunci asimetris (ECDH)
Perhatikan bahwa Keystore dan KeyMint tidak menangani operasi kunci publik untuk kunci asimetris.
Elemen protokol, seperti tujuan, mode, dan padding, serta batasan kontrol akses, ditentukan saat kunci dibuat atau diimpor dan terikat secara permanen ke kunci, sehingga memastikan kunci tidak dapat digunakan dengan cara lain.
Primitif dan mode yang harus didukung oleh
implementasi KeyMint dijelaskan dalam
spesifikasi antarmuka HAL
IKeyMintDevice
.
Implementasi KeyMint yang mendasarinya harus melakukan pembuatan angka acak untuk mendukung pembuatan kunci dan pembuatan padding acak atau vektor inisialisasi (IV). Untuk mendukung hal ini, sistem Android secara berkala memberikan entropi tambahan ke implementasi KeyMint.
Kontrol akses kunci
Kunci berbasis hardware yang tidak pernah dapat diekstrak dari perangkat tidak memberikan keamanan yang memadai jika penyerang dapat menggunakannya sesuka hati (meskipun lebih aman daripada kunci yang dapat diekspor). Oleh karena itu, Keystore harus menerapkan kontrol akses.
Kontrol akses ditentukan sebagai "daftar otorisasi" pasangan tag/nilai. Tag otorisasi adalah bilangan bulat 32-bit dan nilainya adalah berbagai jenis. Beberapa tag dapat diulang untuk menentukan beberapa nilai. Apakah tag dapat diulang ditentukan di antarmuka HAL KeyMint (sebelumnya Keymaster).
Nilai tag yang didukung ditentukan dalam file
Tag.aidl
,
dan masing-masing dikaitkan dengan
TagType
yang menunjukkan jenis nilai terkait (misalnya, bilangan bulat atau byte), dan
apakah nilai tersebut dapat diulang untuk menentukan beberapa nilai yang didukung.
Saat KeyMint membuat kunci, pemanggil menentukan daftar otorisasi untuk kunci. Daftar ini diubah oleh Keystore dan KeyMint untuk menambahkan batasan tambahan, dan implementasi KeyMint yang mendasarinya mengenkode daftar otorisasi akhir ke dalam keyblob yang ditampilkan. Daftar otorisasi yang dienkode secara kriptografis diikat ke dalam keyblob, sehingga setiap upaya untuk mengubah daftar otorisasi (termasuk pengurutan) akan menghasilkan keyblob yang tidak valid dan tidak dapat digunakan untuk operasi kriptografis.
Penerapan hardware versus software
Tidak semua implementasi hardware aman berisi fitur yang sama. Untuk mendukung berbagai pendekatan, KeyMint membedakan antara penerapan kontrol akses yang aman dan tidak aman, atau penerapan hardware dan software.
Hal ini diekspos di KeyMint API dengan kolom securityLevel
dari
jenis
KeyCharacteristics
. Hardware aman bertanggung jawab untuk menempatkan otorisasi di
KeyCharacteristics
dengan tingkat keamanan yang sesuai, berdasarkan hal
yang dapat diterapkan. Informasi ini juga ditampilkan dalam
data pengesahan untuk kunci asimetris: karakteristik kunci
untuk SecurityLevel::TRUSTED_ENVIRONMENT
atau SecurityLevel::STRONGBOX
muncul dalam
daftar hardwareEnforced
, dan karakteristik
untuk SecurityLevel::SOFTWARE
atau
SecurityLevel::KEYSTORE
muncul dalam
daftar softwareEnforced
.
Misalnya, batasan pada interval tanggal dan waktu saat kunci dapat digunakan
biasanya tidak diterapkan oleh lingkungan aman, karena tidak memiliki
akses tepercaya ke informasi tanggal dan waktu. Akibatnya, otorisasi seperti
Tag::ORIGINATION_EXPIRE_DATETIME
diberlakukan oleh Keystore di
Android, dan akan memiliki SecurityLevel::KEYSTORE
.
Untuk mengetahui informasi selengkapnya tentang cara menentukan apakah kunci dan otorisasinya didukung hardware, lihat Pengesahan kunci.
Otorisasi konstruksi pesan kriptografis
Tag berikut digunakan untuk menentukan karakteristik kriptografis operasi menggunakan kunci terkait:
Tag::ALGORITHM
Tag::KEY_SIZE
Tag::BLOCK_MODE
Tag::PADDING
Tag::CALLER_NONCE
Tag::DIGEST
Tag::MGF_DIGEST
Tag berikut dapat diulang, yang berarti beberapa nilai dapat dikaitkan dengan satu kunci:
Tag::BLOCK_MODE
Tag::PADDING
Tag::DIGEST
Tag::MGF_DIGEST
Nilai yang akan digunakan ditentukan pada waktu operasi.
Tujuan
Kunci memiliki kumpulan tujuan terkait, yang dinyatakan sebagai satu atau beberapa
entri otorisasi dengan tag Tag::PURPOSE
, yang menentukan cara
kunci tersebut dapat digunakan. Tujuannya ditentukan dalam
KeyPurpose.aidl
.
Perhatikan bahwa beberapa kombinasi nilai tujuan akan menimbulkan masalah keamanan. Misalnya, kunci RSA yang dapat digunakan untuk mengenkripsi dan menandatangani memungkinkan penyerang yang dapat meyakinkan sistem untuk mendekripsi data arbitrer guna menghasilkan tanda tangan.
Impor kunci
KeyMint mendukung impor:
- Pasangan kunci asimetris dalam format PKCS#8 yang dienkode DER (tanpa enkripsi berbasis sandi)
- Kunci simetris sebagai byte mentah
Untuk memastikan bahwa kunci yang diimpor dapat dibedakan dari kunci yang dihasilkan dengan aman, Tag::ORIGIN
disertakan dalam daftar otorisasi kunci yang sesuai. Misalnya, jika kunci
dibuat di hardware aman, Tag::ORIGIN
dengan
nilai KeyOrigin::GENERATED
akan ditemukan di
daftar hw_enforced
karakteristik kunci, sedangkan kunci
yang diimpor ke hardware
aman memiliki nilai KeyOrigin::IMPORTED
.
Autentikasi pengguna
Implementasi KeyMint yang aman tidak menerapkan autentikasi pengguna, tetapi bergantung pada aplikasi tepercaya lainnya yang melakukannya. Untuk antarmuka yang diterapkan aplikasi ini, lihat halaman Gatekeeper.
Persyaratan autentikasi pengguna ditentukan melalui dua kumpulan tag. Kumpulan pertama menunjukkan metode autentikasi yang mengizinkan penggunaan kunci:
Tag::USER_SECURE_ID
memiliki nilai numerik 64-bit yang menentukan ID pengguna aman yang diberikan dalam token autentikasi aman untuk membuka kunci penggunaan kunci. Jika diulang, kunci dapat digunakan jika salah satu nilai disediakan dalam token autentikasi yang aman.
Kumpulan kedua menunjukkan apakah dan kapan pengguna perlu diautentikasi.
Jika tidak ada tag ini, tetapi Tag::USER_SECURE_ID
ada,
autentikasi diperlukan untuk setiap penggunaan kunci.
Tag::NO_AUTHENTICATION_REQUIRED
menunjukkan bahwa tidak ada autentikasi pengguna yang diperlukan, meskipun akses ke kunci masih dibatasi untuk aplikasi pemilik (dan aplikasi apa pun yang diberi akses).Tag::AUTH_TIMEOUT
adalah nilai numerik yang menentukan, dalam detik, seberapa baru autentikasi pengguna yang diperlukan untuk mengizinkan penggunaan kunci. Waktu tunggu tidak melewati mulai ulang; setelah mulai ulang, semua autentikasi akan dibatalkan. Waktu tunggu dapat ditetapkan ke nilai besar untuk menunjukkan bahwa autentikasi diperlukan sekali per booting (2^32 detik adalah ~136 tahun; mungkin perangkat Android di-reboot lebih sering dari itu).
Memerlukan perangkat yang tidak terkunci
Kunci dengan Tag::UNLOCKED_DEVICE_REQUIRED
hanya dapat digunakan saat
perangkat tidak terkunci. Untuk semantik mendetail, lihat
KeyProtection.Builder#setUnlockedDeviceRequired(boolean)
.
UNLOCKED_DEVICE_REQUIRED
diterapkan oleh Keystore, bukan oleh
KeyMint. Namun, di Android 12 dan yang lebih tinggi, Keystore secara kriptografis
melindungi kunci UNLOCKED_DEVICE_REQUIRED
saat perangkat terkunci
untuk memastikan bahwa, dalam sebagian besar kasus, kunci tersebut tidak dapat digunakan meskipun Keystore
telah disusupi saat perangkat terkunci.
Untuk mencapai hal ini, Keystore "mengenkripsi super" semua
kunci UNLOCKED_DEVICE_REQUIRED
sebelum menyimpannya dalam database,
dan jika memungkinkan, Keystore akan melindungi kunci superenkripsi (kunci super) saat
perangkat dikunci sedemikian rupa sehingga kunci tersebut hanya dapat dipulihkan dengan
membuka kunci perangkat yang berhasil. (Istilah "superenkripsi" digunakan karena lapisan enkripsi ini diterapkan selain lapisan enkripsi yang sudah diterapkan KeyMint ke semua kunci.)
Setiap pengguna (termasuk profil)
memiliki dua kunci super yang terkait dengan UNLOCKED_DEVICE_REQUIRED
:
- Kunci super simetris UnlockedDeviceRequired. Ini adalah
kunci AES‑256‑GCM. API ini mengenkripsi
kunci
UNLOCKED_DEVICE_REQUIRED
yang diimpor atau dibuat saat perangkat tidak terkunci untuk pengguna. - Kunci super asimetris UnlockedDeviceRequired. Ini adalah pasangan kunci
ECDH P‑521. Library ini mengenkripsi kunci
UNLOCKED_DEVICE_REQUIRED
yang diimpor atau dibuat saat perangkat dikunci untuk pengguna. Kunci yang dienkripsi dengan kunci asimetris ini dienkripsi ulang dengan kunci simetris saat pertama kali digunakan (yang hanya dapat terjadi saat perangkat tidak terkunci).
Keystore membuat kunci super ini pada waktu pembuatan pengguna dan menyimpannya di database-nya, yang dienkripsi oleh sandi sintetis pengguna. Hal ini memungkinkannya dipulihkan menggunakan PIN, pola, atau sandi yang setara.
Keystore juga meng-cache kunci super ini dalam memori, sehingga dapat beroperasi pada
kunci UNLOCKED_DEVICE_REQUIRED
. Namun, kunci ini mencoba meng-cache
bagian rahasia kunci ini hanya saat perangkat tidak terkunci untuk pengguna. Saat
perangkat dikunci untuk pengguna, Keystore akan mereset salinan
bagian rahasia kunci super ini yang di-cache, jika memungkinkan. Secara khusus, saat perangkat
dikunci untuk pengguna, Keystore akan memilih dan menerapkan salah satu dari tiga tingkat perlindungan
untuk kunci super UnlockedDeviceRequired pengguna:
- Jika pengguna hanya mengaktifkan PIN, pola, atau sandi, Keystore akan mereset bagian rahasia kunci super yang di-cache. Hal ini membuat kunci super hanya dapat dipulihkan melalui salinan terenkripsi dalam database yang dapat didekripsi hanya dengan PIN, pola, atau sandi yang setara.
- Jika pengguna hanya memiliki biometrik ("kuat") kelas 3 dan PIN, pola, atau sandi diaktifkan, Keystore akan mengatur agar kunci super dapat dipulihkan oleh salah satu biometrik kelas 3 terdaftar pengguna (biasanya sidik jari), sebagai alternatif untuk PIN, pola, atau sandi yang setara. Untuk melakukannya, KeyMint akan membuat kunci AES‑256‑GCM baru, mengenkripsi bagian rahasia kunci super dengan kunci tersebut, mengimpor kunci AES‑256‑GCM ke KeyMint sebagai kunci terikat biometrik yang memerlukan autentikasi biometrik yang berhasil dalam 15 detik terakhir, dan mereset salinan teks biasa dari semua kunci ini ke nol.
- Jika pengguna memiliki biometrik class 1 ("kemudahan"), biometrik class 2 ("lemah"),
atau mengaktifkan agen kepercayaan buka kunci aktif, Keystore akan menyimpan
kunci super dalam cache dalam teks biasa. Dalam hal ini, keamanan kriptografis untuk
kunci
UNLOCKED_DEVICE_REQUIRED
tidak disediakan. Pengguna dapat menghindari penggantian yang kurang aman ini dengan tidak mengaktifkan metode buka kunci ini. Metode buka kunci yang paling umum yang termasuk dalam kategori ini adalah buka kunci dengan wajah di banyak perangkat, dan buka kunci dengan smartwatch yang disambungkan.
Saat perangkat dibuka kuncinya untuk pengguna, Keystore akan memulihkan kunci super UnlockedDeviceRequired pengguna jika memungkinkan. Untuk membuka kunci yang setara dengan PIN, pola, atau sandi, kunci ini mendekripsi salinan kunci yang disimpan di database. Jika tidak, sistem akan memeriksa apakah telah menyimpan salinan kunci ini yang dienkripsi dengan kunci terikat biometrik, dan jika ya, mencoba mendekripsinya. Hal ini hanya berhasil jika pengguna telah berhasil diautentikasi dengan biometrik class 3 dalam 15 detik terakhir, yang diterapkan oleh KeyMint (bukan Keystore).
Binding klien
Binding klien, yaitu pengaitan kunci dengan aplikasi klien
tertentu, dilakukan melalui client ID opsional dan beberapa data klien opsional
(masing-masing Tag::APPLICATION_ID
dan Tag::APPLICATION_DATA
). Keystore memperlakukan nilai ini sebagai blob buram, hanya memastikan bahwa
blob yang sama yang ditampilkan selama pembuatan/impor kunci ditampilkan untuk setiap
penggunaan dan identik byte demi byte. Data binding klien tidak ditampilkan oleh KeyMint. Pemanggil harus mengetahuinya untuk menggunakan kunci.
Fitur ini tidak ditampilkan ke aplikasi.
Masa berlaku
Keystore mendukung pembatasan penggunaan kunci berdasarkan tanggal. Awal validitas kunci dan
masa berlaku kunci dapat dikaitkan dengan kunci dan Keystore menolak untuk
melakukan operasi kunci jika tanggal/waktu saat ini berada di luar rentang
yang valid. Rentang validitas kunci ditentukan dengan tag
Tag::ACTIVE_DATETIME
,
Tag::ORIGINATION_EXPIRE_DATETIME
, dan
Tag::USAGE_EXPIRE_DATETIME
. Perbedaan antara
"origination" dan "usage" didasarkan pada apakah kunci digunakan untuk
"originate" ciphertext/tanda tangan/dll. baru, atau untuk "menggunakan" ciphertext/tanda tangan/dll. yang ada. Perhatikan bahwa perbedaan ini tidak ditampilkan ke
aplikasi.
Tag Tag::ACTIVE_DATETIME
,
Tag::ORIGINATION_EXPIRE_DATETIME
,
dan Tag::USAGE_EXPIRE_DATETIME
bersifat opsional. Jika tag
tidak ada, diasumsikan bahwa kunci yang
dipermasalahkan selalu dapat digunakan untuk mendekripsi/memverifikasi pesan.
Karena waktu jam dinding disediakan oleh dunia yang tidak aman, tag terkait masa berlaku berada dalam daftar yang diterapkan software.
Binding root of trust
Keystore mengharuskan kunci terikat ke root of trust, yang merupakan bitstring yang disediakan ke hardware aman KeyMint selama startup, sebaiknya oleh bootloader. Bitstring ini terikat secara kriptografis ke setiap kunci yang dikelola oleh KeyMint.
Root of trust terdiri dari hash kunci publik yang digunakan untuk memverifikasi tanda tangan pada image booting dan status kunci perangkat. Jika kunci publik diubah untuk memungkinkan penggunaan image sistem yang berbeda atau jika status kunci diubah, tidak ada kunci yang dilindungi KeyMint yang dibuat oleh sistem sebelumnya yang dapat digunakan kecuali root of trust sebelumnya dipulihkan dan sistem yang ditandatangani oleh kunci tersebut di-booting. Tujuannya adalah untuk meningkatkan nilai kontrol akses kunci yang diterapkan software dengan membuat sistem operasi yang diinstal penyerang tidak dapat menggunakan kunci KeyMint.
Pembuatan ulang seed generator angka acak
Karena hardware aman menghasilkan angka acak untuk materi kunci dan vektor inisialisasi (IV), dan karena generator angka acak hardware mungkin tidak selalu sepenuhnya dapat dipercaya, HAL KeyMint menyediakan antarmuka untuk memungkinkan Keystore memberikan entropi tambahan, yang dicampur ke dalam angka acak yang dihasilkan.
Gunakan generator angka acak hardware sebagai sumber seed utama. Data seed yang disediakan melalui API eksternal tidak boleh menjadi satu-satunya sumber keacakan yang digunakan untuk pembuatan angka. Selain itu, operasi pencampuran yang digunakan harus memastikan bahwa output acak tidak dapat diprediksi jika salah satu sumber benih tidak dapat diprediksi.