Halaman ini berisi informasi tentang fitur kriptografi Keystore di Android 6.0 dan di atasnya.
Primitif kriptografi
Keystore menyediakan kategori operasi berikut:
- Pembuatan kunci
- Impor dan ekspor kunci asimetris (tanpa pembungkusan kunci)
- Impor kunci simetris mentah (tanpa pembungkus kunci)
- Enkripsi dan dekripsi asimetris dengan mode padding yang sesuai
- Penandatanganan dan verifikasi asimetris dengan mode digesting dan padding yang sesuai
- Enkripsi dan dekripsi simetris dalam mode yang sesuai, termasuk mode AEAD
- Pembuatan dan verifikasi kode otentikasi pesan simetris
Elemen protokol, seperti tujuan, mode dan padding, serta batasan kontrol akses , ditentukan ketika kunci dibuat atau diimpor dan secara permanen terikat ke kunci, memastikan kunci tidak dapat digunakan dengan cara lain.
Selain daftar di atas, ada satu layanan lagi yang disediakan oleh implementasi Keymaster, tetapi tidak diekspos sebagai API: Pembuatan angka acak. Ini digunakan secara internal untuk pembuatan kunci, Vektor Inisialisasi (IV), padding acak, dan elemen protokol aman lainnya yang memerlukan keacakan.
Primitif yang diperlukan
Semua implementasi Keymaster menyediakan:
- RSA
- Dukungan kunci 2048, 3072, dan 4096-bit
- Dukungan untuk eksponen publik F4 (2^16+1)
- Mode bantalan untuk penandatanganan RSA:
- RSASSA-PSS (
PaddingMode::RSA_PSS
) - RSASSA-PKCS1-v1_5 (
PaddingMode::RSA_PKCS1_1_5_SIGN
)
- RSASSA-PSS (
- Mode intisari untuk penandatanganan RSA:
- SHA-256
- Mode padding untuk enkripsi/dekripsi RSA:
- Tidak berlapis
- RSAES-OAEP (
PaddingMode::RSA_OAEP
) - RSAES-PKCS1-v1_5 (
PaddingMode::RSA_PKCS1_1_5_ENCRYPT
)
- PAUD
- Dukungan kunci 224, 256, 384, dan 521-bit didukung, masing-masing menggunakan kurva NIST P-224, P-256, P-384, dan P-521
- Mode intisari untuk ECDSA:
- Tidak ada intisari (tidak digunakan lagi, akan dihapus di masa mendatang)
- SHA-256
- AES
- 128 dan 256-bit kunci yang didukung
- CBC , RKT, ECB, dan GCM. Implementasi GCM tidak mengizinkan penggunaan tag yang lebih kecil dari 96 bit atau panjang nonce selain 96 bit.
- Mode
PaddingMode::NONE
danPaddingMode::PKCS7
didukung untuk mode CBC dan ECB. Tanpa padding, enkripsi mode CBC atau ECB gagal jika inputnya bukan kelipatan dari ukuran blok.
- HMAC SHA-256 , dengan ukuran kunci apa pun hingga setidaknya 32 byte.
SHA1 dan anggota keluarga SHA2 lainnya (SHA-224, SHA384, dan SHA512) sangat disarankan untuk penerapan Keymaster. Keystore menyediakannya dalam perangkat lunak jika implementasi Keymaster perangkat keras tidak menyediakannya.
Beberapa primitif juga direkomendasikan untuk interoperabilitas dengan sistem lain:
- Ukuran kunci yang lebih kecil untuk RSA
- Eksponen publik sewenang-wenang untuk RSA
Kontrol akses kunci
Kunci berbasis perangkat keras yang tidak pernah dapat diekstraksi dari perangkat tidak memberikan banyak keamanan jika penyerang dapat menggunakannya sesuka hati (meskipun lebih aman daripada kunci yang dapat dieksfiltrasi). Oleh karena itu, sangat 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 beragam. Beberapa tag dapat diulang untuk menentukan beberapa nilai. Apakah tag dapat diulang ditentukan dalam dokumentasi untuk tag tersebut . Saat kunci dibuat, pemanggil menentukan daftar otorisasi. Implementasi Keymaster yang mendasari Keystore memodifikasi daftar untuk menentukan beberapa informasi tambahan, seperti apakah kunci tersebut memiliki perlindungan rollback, dan mengembalikan daftar otorisasi "final", yang dikodekan ke dalam gumpalan kunci yang dikembalikan. Setiap upaya untuk menggunakan kunci untuk operasi kriptografi gagal jika daftar otorisasi akhir diubah.
Untuk Keymaster 2 dan sebelumnya, kumpulan tag yang mungkin ditentukan dalam enumerasi keymaster_authorization_tag_t
dan diperbaiki secara permanen (meskipun dapat diperpanjang). Nama diawali dengan KM_TAG
. Empat bit teratas dari ID tag digunakan untuk menunjukkan jenisnya.
Keymaster 3 mengubah awalan KM_TAG
menjadi Tag::
.
Jenis yang mungkin termasuk:
ENUM
: Banyak nilai tag didefinisikan dalam enumerasi. Misalnya, kemungkinan nilai TAG::PURPOSE
ditentukan dalam enum keymaster_purpose_t
.
ENUM_REP
: Sama seperti ENUM
, kecuali bahwa tag dapat diulang dalam daftar otorisasi. Pengulangan menunjukkan beberapa nilai resmi. Misalnya, kunci enkripsi kemungkinan memiliki KeyPurpose::ENCRYPT
dan KeyPurpose::DECRYPT
.
UINT
: 32-bit unsigned integer. Contoh: TAG::KEY_SIZE
UINT_REP
: Sama seperti UINT
, kecuali bahwa tag dapat diulang dalam daftar otorisasi. Pengulangan menunjukkan beberapa nilai resmi.
ULONG
: 64-bit unsigned integer. Contoh: TAG::RSA_PUBLIC_EXPONENT
ULONG_REP
: Sama seperti ULONG
, kecuali bahwa tag dapat diulang dalam daftar otorisasi. Pengulangan menunjukkan beberapa nilai resmi.
DATE
: Nilai tanggal/waktu, dinyatakan dalam milidetik sejak 1 Januari 1970. Contoh: TAG::PRIVKEY_EXPIRE_DATETIME
BOOL
: Benar atau salah. Tag bertipe BOOL
dianggap "false" jika tag tidak ada dan "true" jika ada. Contoh: TAG::ROLLBACK_RESISTANT
BIGNUM
: Bilangan bulat panjang sewenang-wenang, dinyatakan sebagai array byte dalam urutan big-endian. Contoh: TAG::RSA_PUBLIC_EXPONENT
BYTES
: Urutan byte. Contoh: TAG::ROOT_OF_TRUST
Perangkat keras vs. penegakan perangkat lunak
Tidak semua implementasi perangkat keras yang aman berisi fitur yang sama. Untuk mendukung berbagai pendekatan, Keymaster membedakan antara penegakan kontrol akses dunia yang aman dan tidak aman, atau penegakan perangkat keras dan perangkat lunak, masing-masing.
Semua implementasi:
- Terapkan pencocokan tepat (bukan penegakan) semua otorisasi. Daftar otorisasi dalam gumpalan kunci sama persis dengan otorisasi yang dikembalikan selama pembuatan kunci, termasuk pemesanan. Setiap ketidakcocokan menyebabkan diagnosis kesalahan.
- Deklarasikan otorisasi yang nilai semantiknya diterapkan.
Mekanisme API untuk mendeklarasikan otorisasi yang didukung perangkat keras ada di struktur keymaster_key_characteristics_t
. Ini membagi daftar otorisasi menjadi dua sub-daftar, hw_enforced
dan sw_enforced
. Perangkat keras yang aman bertanggung jawab untuk menempatkan nilai yang sesuai di masing-masing, berdasarkan apa yang dapat ditegakkan.
Selain itu, Keystore menerapkan penegakan semua otorisasi berbasis perangkat lunak, baik yang diberlakukan oleh perangkat keras yang aman atau tidak.
Misalnya, pertimbangkan implementasi berbasis TrustZone yang tidak mendukung kedaluwarsa kunci. Kunci dengan tanggal kedaluwarsa masih dapat dibuat. Daftar otorisasi kunci tersebut akan menyertakan tag TAG::ORIGINATION_EXPIRE_DATETIME
dengan tanggal kedaluwarsa. Permintaan ke Keystore untuk karakteristik utama akan menemukan tag ini dalam daftar sw_enforced
dan perangkat keras yang aman tidak akan memberlakukan persyaratan kedaluwarsa. Namun, upaya untuk menggunakan kunci setelah kedaluwarsa akan ditolak oleh Keystore.
Jika perangkat kemudian ditingkatkan dengan perangkat keras aman yang mendukung kedaluwarsa, maka permintaan untuk karakteristik utama akan menemukan TAG::ORIGINATION_EXPIRE_DATETIME
dalam daftar hw_enforced
, dan upaya untuk menggunakan kunci setelah kedaluwarsa akan gagal meskipun keystore entah bagaimana ditumbangkan atau dilewati .
Untuk informasi selengkapnya tentang menentukan apakah kunci didukung perangkat keras, lihat Pengesahan kunci .
Otorisasi pembuatan pesan kriptografis
Tag berikut digunakan untuk menentukan karakteristik kriptografik operasi menggunakan kunci terkait: TAG::ALGORITHM
, TAG::KEY_SIZE
, TAG::BLOCK_MODE
, TAG::PADDING
, TAG::CALLER_NONCE
, dan TAG::DIGEST
TAG::PADDING
, TAG::DIGEST
, dan PaddingMode::BLOCK_MODE
dapat diulang, artinya beberapa nilai dapat dikaitkan dengan satu kunci, dan nilai yang akan digunakan ditentukan pada waktu pengoperasian.
Tujuan
Kunci memiliki serangkaian tujuan terkait, yang dinyatakan sebagai satu atau beberapa entri otorisasi dengan tag TAG::PURPOSE
, yang menentukan cara penggunaannya. Tujuannya adalah:
-
KeyPurpose::ENCRYPT
-
KeyPurpose::DECRYPT
-
KeyPurpose::SIGN
-
KeyPurpose::VERIFY
Kunci apa pun dapat memiliki subset apa pun dari tujuan ini. Perhatikan bahwa beberapa kombinasi menciptakan masalah keamanan. Misalnya, kunci RSA yang dapat digunakan untuk mengenkripsi dan menandatangani memungkinkan penyerang yang dapat meyakinkan sistem untuk mendekripsi data arbitrer untuk menghasilkan tanda tangan.
Impor dan ekspor
Keymaster hanya mendukung ekspor kunci publik, dalam format X.509, dan impor:
- Pasangan kunci publik dan pribadi dalam format PKCS#8 yang disandikan DER, tanpa enkripsi berbasis kata 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 perangkat keras yang aman, TAG::ORIGIN
dengan nilai KeyOrigin::GENERATED
akan ditemukan dalam daftar hw_enforced
karakteristik kunci, sedangkan kunci yang diimpor ke perangkat keras aman akan memiliki nilai KeyOrigin::IMPORTED
.
Otentikasi pengguna
Implementasi Secure Keymaster tidak mengimplementasikan autentikasi pengguna, tetapi bergantung pada aplikasi tepercaya lain yang menerapkannya. Untuk antarmuka yang diterapkan aplikasi ini, lihat halaman Gatekeeper .
Persyaratan otentikasi pengguna ditentukan melalui dua set tag. Set pertama menunjukkan pengguna mana yang dapat menggunakan kunci:
-
TAG::ALL_USERS
menunjukkan bahwa kunci dapat digunakan oleh semua pengguna. Jika ada,TAG::USER_ID
danTAG::USER_SECURE_ID
tidak ada. -
TAG::USER_ID
memiliki nilai numerik yang menentukan ID pengguna yang berwenang. Perhatikan bahwa ini adalah ID pengguna Android (untuk multi-pengguna), bukan UID aplikasi, dan hanya diterapkan oleh perangkat lunak yang tidak aman. Jika ada,TAG::ALL_USERS
tidak ada. -
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 satu pun dari tag ini ada, tetapi TAG::USER_SECURE_ID
ada, autentikasi diperlukan untuk setiap penggunaan kunci.
-
NO_AUTHENTICATION_REQUIRED
menunjukkan bahwa autentikasi pengguna tidak diperlukan, meskipun kuncinya tetap hanya dapat digunakan oleh aplikasi yang berjalan sebagai pengguna yang ditentukan olehTAG::USER_ID
. -
TAG::AUTH_TIMEOUT
adalah nilai numerik yang menentukan, dalam hitungan detik, seberapa segar autentikasi pengguna perlu untuk mengotorisasi penggunaan kunci. Ini hanya berlaku untuk operasi kunci pribadi/rahasia. Operasi kunci publik tidak memerlukan otentikasi. Timeout tidak melewati reboot; setelah reboot, semua kunci "tidak pernah diautentikasi." Batas waktu dapat diatur ke nilai yang besar untuk menunjukkan bahwa otentikasi diperlukan sekali per boot (2^32 detik adalah ~136 tahun; mungkin perangkat Android di-boot ulang lebih sering dari itu).
Pengikatan klien
Pengikatan klien, pengaitan kunci dengan aplikasi klien tertentu, dilakukan melalui ID klien opsional dan beberapa data klien opsional ( TAG::APPLICATION_ID
dan TAG::APPLICATION_DATA
, masing-masing). Keystore memperlakukan nilai-nilai ini sebagai gumpalan buram, hanya memastikan bahwa gumpalan yang sama yang disajikan selama pembuatan/impor kunci disajikan untuk setiap penggunaan dan identik byte-untuk-byte. Data pengikatan klien tidak dikembalikan oleh Keymaster. Penelepon harus mengetahuinya agar dapat menggunakan kunci tersebut.
Fitur ini tidak terkena aplikasi.
kedaluwarsa
Keystore mendukung pembatasan penggunaan kunci berdasarkan tanggal. Awal validitas kunci dan kedaluwarsa kunci dapat dikaitkan dengan kunci dan Keymaster 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 "asal" dan "penggunaan" didasarkan pada apakah kunci tersebut digunakan untuk "menghasilkan" ciphertext/tanda tangan/dll baru, atau untuk "menggunakan" ciphertext/tanda tangan/dll yang ada. Perhatikan bahwa perbedaan ini tidak terkena aplikasi.
TAG::ACTIVE_DATETIME
, TAG::ORIGINATION_EXPIRE_DATETIME
, dan TAG::USAGE_EXPIRE_DATETIME
adalah 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, kecil kemungkinan bahwa tag terkait kedaluwarsa akan ada dalam daftar yang didukung perangkat keras. Penegakan perangkat keras kedaluwarsa akan mengharuskan dunia yang aman entah bagaimana mendapatkan waktu dan data tepercaya, misalnya melalui protokol respons tantangan dengan server waktu jarak jauh tepercaya.
Akar kepercayaan mengikat
Keystore memerlukan kunci untuk diikat ke akar kepercayaan, yang merupakan bitstring yang disediakan untuk perangkat keras aman Keymaster selama startup, sebaiknya oleh bootloader. Bitstring ini terikat secara kriptografis ke setiap kunci yang dikelola oleh Keymaster.
Akar kepercayaan terdiri dari kunci publik yang digunakan untuk memverifikasi tanda tangan pada gambar boot dan status kunci perangkat. Jika kunci publik diubah untuk memungkinkan citra sistem yang berbeda digunakan atau jika status kunci diubah, maka tidak ada kunci yang dilindungi Keymaster yang dibuat oleh sistem sebelumnya yang dapat digunakan, kecuali jika akar kepercayaan sebelumnya dipulihkan dan sistem yang ditandatangani oleh kunci itu di-boot. Tujuannya adalah untuk meningkatkan nilai kontrol akses kunci yang didukung perangkat lunak dengan membuat sistem operasi yang dipasang penyerang tidak mungkin menggunakan kunci Keymaster.
Kunci mandiri
Beberapa perangkat keras aman Keymaster dapat memilih untuk menyimpan materi kunci secara internal dan mengembalikan pegangan daripada materi kunci terenkripsi. Atau mungkin ada kasus lain di mana kunci tidak dapat digunakan sampai beberapa komponen sistem dunia tidak aman atau aman lainnya tersedia. Keymaster HAL memungkinkan pemanggil untuk meminta kunci menjadi "mandiri", melalui tag TAG::STANDALONE
, yang berarti bahwa tidak diperlukan sumber daya selain blob dan sistem Keymaster yang sedang berjalan. Tag yang terkait dengan kunci dapat diperiksa untuk melihat apakah kunci itu mandiri. Saat ini, hanya dua nilai yang didefinisikan:
-
KeyBlobUsageRequirements::STANDALONE
-
KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM
Fitur ini tidak terkena aplikasi.
Kecepatan
Saat dibuat, kecepatan penggunaan maksimum dapat ditentukan dengan TAG::MIN_SECONDS_BETWEEN_OPS
. Implementasi TrustZone menolak untuk melakukan operasi kriptografi dengan kunci tersebut jika operasi dilakukan kurang dari TAG::MIN_SECONDS_BETWEEN_OPS
detik sebelumnya.
Pendekatan sederhana untuk menerapkan batas kecepatan adalah tabel ID kunci dan stempel waktu penggunaan terakhir. Tabel ini kemungkinan akan berukuran terbatas, tetapi menampung setidaknya 16 entri. Jika tabel penuh dan tidak ada entri yang dapat diperbarui atau dibuang, implementasi perangkat keras yang aman "fail safe", lebih memilih untuk menolak semua operasi kunci dengan kecepatan terbatas hingga salah satu entri kedaluwarsa. Semua entri dapat kedaluwarsa setelah reboot.
Kunci juga dapat dibatasi hingga n penggunaan per boot dengan TAG::MAX_USES_PER_BOOT
. Ini juga memerlukan tabel pelacakan, yang menampung setidaknya empat kunci dan juga gagal aman. Perhatikan bahwa aplikasi tidak akan dapat membuat kunci terbatas per boot. Fitur ini tidak diekspos melalui Keystore dan dicadangkan untuk operasi sistem.
Fitur ini tidak terkena aplikasi.
Pembibitan ulang generator nomor acak
Karena perangkat keras yang aman menghasilkan nomor acak untuk materi kunci dan Vektor Inisialisasi (IV), dan karena perangkat keras pembuat nomor acak mungkin tidak selalu dapat dipercaya sepenuhnya, Keymaster HAL menyediakan antarmuka untuk memungkinkan klien memberikan entropi tambahan yang akan dicampur ke dalam acak. angka yang dihasilkan.
Gunakan generator nomor acak perangkat keras sebagai sumber benih utama. Data benih yang disediakan melalui API eksternal tidak dapat menjadi satu-satunya sumber keacakan yang digunakan untuk pembuatan angka. Selanjutnya, operasi pencampuran yang digunakan perlu memastikan bahwa keluaran acak tidak dapat diprediksi jika salah satu sumber benih tidak dapat diprediksi.
Fitur ini tidak diekspos ke aplikasi tetapi digunakan oleh kerangka kerja, yang secara teratur menyediakan entropi tambahan, yang diambil dari instance Java SecureRandom, ke perangkat keras yang aman.