Fitur

Halaman ini berisi informasi tentang fitur kriptografis Android Keystore, seperti yang disediakan oleh implementasi KeyMint (atau Keymaster) yang mendasarinya.

Primitif kriptografis

Keystore menyediakan kategori operasi berikut:

  • Pembuatan kunci, yang menghasilkan materi kunci pribadi atau rahasia yang hanya dapat diakses oleh lingkungan yang 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, semuanya ditandatangani oleh kunci yang dirantai 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)

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 dapat diekstrak dari perangkat tidak memberikan banyak keamanan jika penyerang dapat menggunakannya sesuka hati (meskipun lebih aman daripada kunci yang dapat dieksfiltrasi). Oleh karena itu, penting bagi Keystore untuk menerapkan kontrol akses.

Kontrol akses didefinisikan sebagai "daftar otorisasi" dari pasangan tag/nilai. Tag otorisasi adalah bilangan bulat 32-bit dan nilainya memiliki berbagai jenis. Beberapa tag dapat diulang untuk menentukan beberapa nilai. Apakah tag dapat diulang ditentukan dalam 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 tersebut. 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 terikat secara kriptografis 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.

Penegakan hardware versus software

Tidak semua implementasi hardware yang 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 yang aman bertanggung jawab untuk menempatkan otorisasi di KeyCharacteristics dengan tingkat keamanan yang sesuai, berdasarkan apa 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 yang aman, karena lingkungan tersebut tidak memiliki akses yang dapat dipercaya ke informasi tanggal dan waktu. Akibatnya, otorisasi seperti Tag::ORIGINATION_EXPIRE_DATETIME diterapkan oleh Keystore di Android, dan akan memiliki SecurityLevel::KEYSTORE.

Untuk mengetahui informasi selengkapnya tentang cara menentukan apakah kunci dan otorisasi kunci 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 penggunaannya. Tujuan ditentukan dalam KeyPurpose.aidl.

Perhatikan bahwa beberapa kombinasi nilai tujuan dapat 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 berenkode DER (tanpa enkripsi berbasis sandi)
  • Kunci simetris sebagai byte mentah

Untuk memastikan bahwa kunci yang diimpor dapat dibedakan dari kunci yang dibuat dengan aman, Tag::ORIGIN disertakan dalam daftar otorisasi kunci yang sesuai. Misalnya, jika kunci dibuat di hardware yang aman, Tag::ORIGIN dengan nilai KeyOrigin::GENERATED akan ditemukan dalam daftar hw_enforced karakteristik kunci, sedangkan kunci yang diimpor ke hardware yang aman memiliki nilai KeyOrigin::IMPORTED.

Autentikasi pengguna

Implementasi KeyMint yang aman tidak mengimplementasikan autentikasi pengguna, tetapi bergantung pada aplikasi tepercaya lain yang melakukannya. Untuk antarmuka yang diimplementasikan oleh aplikasi ini, lihat halaman Gatekeeper.

Persyaratan autentikasi pengguna ditentukan melalui dua set tag. Set pertama menunjukkan metode autentikasi yang mengizinkan penggunaan kunci:

  • Tag::USER_SECURE_ID memiliki nilai numerik 64-bit yang menentukan ID pengguna aman yang disediakan dalam token autentikasi aman untuk membuka kunci penggunaan kunci. Jika diulang, kunci dapat digunakan jika salah satu nilai disediakan dalam token autentikasi yang aman.

Set kedua menunjukkan apakah dan kapan pengguna perlu diautentikasi. Jika tidak ada tag ini, tetapi ada Tag::USER_SECURE_ID, autentikasi diperlukan untuk setiap penggunaan kunci.

  • Tag::NO_AUTHENTICATION_REQUIRED menunjukkan bahwa autentikasi pengguna tidak 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 harus dilakukan untuk mengizinkan penggunaan kunci. Waktu tunggu tidak melewati mulai ulang; setelah mulai ulang, semua autentikasi tidak valid. Waktu tunggu dapat ditetapkan ke nilai yang besar untuk menunjukkan bahwa autentikasi diperlukan sekali per booting (2^32 detik adalah ~136 tahun; perangkat Android mungkin 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 melindungi kunci UNLOCKED_DEVICE_REQUIRED secara kriptografis saat perangkat terkunci untuk memastikan bahwa, dalam sebagian besar kasus, kunci tersebut tidak dapat digunakan meskipun Keystore disusupi saat perangkat terkunci.

Semua kriptografi dan pembuatan angka acak yang dijelaskan di bagian ini menggunakan BoringSSL, kecuali jika penggunaan KeyMint disebutkan secara eksplisit. Semua secret akan di-zeroize segera setelah tidak lagi diperlukan.

Kunci super UnlockedDeviceRequired

Untuk melindungi kunci UNLOCKED_DEVICE_REQUIRED secara kriptografis, Keystore "mengenkripsi super" kunci tersebut sebelum menyimpannya di databasenya. Jika memungkinkan, fitur ini melindungi kunci superenkripsi (kunci super) saat perangkat terkunci 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 telah diterapkan KeyMint ke semua kunci.)

Setiap pengguna (termasuk profil) memiliki dua kunci super yang terkait dengan UNLOCKED_DEVICE_REQUIRED:

  • Kunci super simetris UnlockedDeviceRequired. Kunci ini adalah kunci AES‑256‑GCM. Sistem ini mengenkripsi kunci UNLOCKED_DEVICE_REQUIRED yang diimpor, dibuat, atau digunakan saat perangkat tidak terkunci untuk pengguna.
  • Kunci super asimetris UnlockedDeviceRequired. Ini adalah pasangan kunci ECDH P‑521. Kunci ini mengenkripsi kunci UNLOCKED_DEVICE_REQUIRED yang diimpor atau dibuat saat perangkat dikunci untuk pengguna. Untuk mengetahui detail selengkapnya, lihat Menyimpan kunci saat perangkat terkunci.

Membuat dan melindungi kunci super

Saat pengguna dibuat, Keystore akan membuat kunci super UnlockedDeviceRequired pengguna dan menyimpannya di databasenya, yang dienkripsi (secara tidak langsung) oleh sandi sintetis pengguna:

  1. Server sistem memperoleh sandi Keystore pengguna dari sandi sintetis pengguna menggunakan KDF SP800‑108.
  2. Server sistem meneruskan sandi Keystore pengguna ke Keystore.
  3. Keystore membuat kunci super pengguna.
  4. Untuk setiap kunci super pengguna:
    1. Keystore menghasilkan salt acak.
    2. Keystore memperoleh kunci AES‑256‑GCM dari sandi Keystore pengguna dan salt menggunakan HKDF‑SHA256.
    3. Keystore mengenkripsi bagian rahasia dari kunci super menggunakan kunci AES‑256‑GCM ini.
    4. Keystore menyimpan kunci super terenkripsi dan salt-nya dalam database-nya. Jika kunci tersebut adalah kunci asimetris, bagian publik dari kunci tersebut juga disimpan tanpa dienkripsi.

Prosedur ini memungkinkan kunci super ini didekripsi saat sandi sintetis pengguna diketahui, seperti saat PIN, pola, atau sandi pengguna yang benar dimasukkan.

Keystore juga meng-cache kunci super ini dalam memori, sehingga dapat beroperasi pada kunci UNLOCKED_DEVICE_REQUIRED. Namun, sistem akan mencoba meng-cache bagian rahasia dari kunci ini hanya saat perangkat tidak terkunci untuk pengguna. Saat perangkat dikunci untuk pengguna, Keystore akan mengosongkan salinan yang di-cache dari bagian rahasia kunci super ini, 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 mengosongkan bagian rahasia dari kunci super yang di-cache. Hal ini membuat kunci super hanya dapat dipulihkan melalui salinan terenkripsi dalam database yang hanya dapat didekripsi dengan PIN, pola, atau sandi yang setara.
  • Jika pengguna hanya mengaktifkan biometrik class 3 ("kuat") dan PIN, pola, atau sandi, Keystore akan mengatur agar kunci super dapat dipulihkan oleh salah satu biometrik class 3 yang didaftarkan pengguna (biasanya sidik jari), sebagai alternatif untuk PIN, pola, atau sandi yang setara. Untuk melakukannya, KeyMint membuat kunci AES‑256‑GCM baru, mengenkripsi bagian rahasia kunci super dengannya, mengimpor kunci AES‑256‑GCM ke KeyMint sebagai kunci terikat biometrik yang memerlukan autentikasi biometrik yang berhasil dalam 15 detik terakhir, dan mengosongkan salinan teks biasa dari semua kunci ini.
  • Jika pengguna mengaktifkan biometrik class 1 ("kenyamanan"), biometrik class 2 ("lemah"), atau agen tepercaya 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 paling umum yang termasuk dalam kategori ini adalah buka 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 pembukaan kunci yang setara dengan PIN, pola, atau sandi, kunci ini mendekripsi salinan kunci yang disimpan dalam database. Jika tidak, sistem akan memeriksa apakah sistem menyimpan salinan kunci ini yang dienkripsi dengan kunci terikat biometrik, dan jika ya, sistem akan mencoba mendekripsinya. Hal ini hanya berhasil jika pengguna telah berhasil melakukan autentikasi dengan biometrik class 3 dalam 15 detik terakhir, yang diterapkan oleh KeyMint (bukan Keystore).

Menyimpan kunci saat perangkat terkunci

Keystore memungkinkan pengguna mengimpor dan membuat kunci UNLOCKED_DEVICE_REQUIRED saat perangkat dikunci. Sistem ini menggunakan skema enkripsi hibrid untuk memastikan bahwa data hanya dapat didekripsi saat perangkat dibuka kuncinya nanti:

  • Enkripsi (mengimpor atau membuat kunci UNLOCKED_DEVICE_REQUIRED saat perangkat terkunci):
    1. Keystore membuat pasangan kunci ECDH P‑521 sementara yang baru.
    2. Keystore menghasilkan rahasia bersama dengan melakukan perjanjian kunci ECDH antara kunci pribadi pasangan kunci sementara ini dan bagian publik dari kunci super asimetris UnlockedDeviceRequired.
    3. Keystore menghasilkan salt acak.
    4. Keystore memperoleh kunci AES‑256‑GCM dari rahasia bersama dan salt menggunakan HKDF‑SHA256.
    5. Keystore mengenkripsi kunci UNLOCKED_DEVICE_REQUIRED menggunakan kunci AES‑256‑GCM ini.
    6. Keystore menyimpan kunci UNLOCKED_DEVICE_REQUIRED yang dienkripsi, salt, dan setengah bagian publik dari pasangan kunci sementara dalam database-nya.
  • Dekripsi (menggunakan kunci UNLOCKED_DEVICE_REQUIRED yang dibuat saat perangkat tidak terkunci):
    1. Keystore memuat kunci UNLOCKED_DEVICE_REQUIRED yang dienkripsi, salt, dan bagian publik dari pasangan kunci sementara dari databasenya.
    2. Keystore menghasilkan rahasia bersama dengan melakukan perjanjian kunci ECDH antara setengah publik dari pasangan kunci sementara dan setengah pribadi dari kunci super asimetris UnlockedDeviceRequired. Kunci pribadi tersedia karena perangkat tidak terkunci.
    3. Keystore memperoleh kunci AES‑256‑GCM dari rahasia bersama dan salt menggunakan HKDF‑SHA256. Kunci AES‑256‑GCM ini sama dengan kunci yang diperoleh selama enkripsi.
    4. Keystore mendekripsi kunci UNLOCKED_DEVICE_REQUIRED menggunakan kunci AES‑256‑GCM.
    5. Keystore mengenkripsi ulang kunci UNLOCKED_DEVICE_REQUIRED menggunakan kunci super simetris UnlockedDeviceRequired. Tindakan ini tidak memengaruhi properti keamanan kunci, tetapi memungkinkan kunci diakses lebih cepat nantinya.

Fitur ini memungkinkan aplikasi menyimpan data saat perangkat terkunci, sehingga data hanya dapat didekripsi saat perangkat tidak terkunci. Untuk melakukannya, aplikasi harus mengikuti langkah-langkah berikut:

  1. Buat kunci AES‑256‑GCM di luar Keystore.
  2. Mengenkripsi data menggunakan kunci AES‑256‑GCM.
  3. Impor kunci AES‑256‑GCM ke Keystore dengan perlindungan kunci setUnlockedDeviceRequired(true) yang ditetapkan.
  4. Menghapus salinan asli kunci.

Untuk mendekripsi data saat perangkat tidak terkunci, gunakan kunci yang diimpor ke Keystore.

Binding klien

Pengikatan 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-for-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 masa berlaku 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 "pembuatan" dan "penggunaan" didasarkan pada apakah kunci digunakan untuk "membuat" ciphertext/tanda tangan/dll. baru, atau untuk "menggunakan" ciphertext/tanda tangan/dll. yang sudah 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 dimaksud 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.

Pengikatan root of trust

Keystore mengharuskan kunci terikat ke root of trust, yang merupakan bitstring yang diberikan 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 boot image dan status kunci perangkat. Jika kunci publik diubah untuk mengizinkan 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 jika 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.

Penyemaian ulang generator angka acak

Karena hardware yang 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 awal yang diberikan 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 seed tidak dapat diprediksi.