Keystore menyediakan tempat yang lebih aman untuk membuat, menyimpan, dan menggunakan kunci kriptografi dengan cara yang terkontrol. Jika penyimpanan kunci yang didukung hardware tersedia dan digunakan, materi kunci akan lebih aman terhadap ekstraksi dari perangkat, dan Keymaster akan menerapkan batasan yang sulit dirusak.
Namun, hal ini hanya berlaku jika kunci keystore diketahui berada di penyimpanan yang didukung hardware. Di Keymaster 1, tidak ada cara bagi aplikasi atau server jarak jauh untuk memverifikasi dengan andal apakah hal ini terjadi. Daemon keystore memuat HAL keymaster yang tersedia dan mempercayai apa pun yang dikatakan HAL terkait dukungan hardware kunci.
Untuk mengatasi hal ini, Keymaster memperkenalkan pengesahan kunci di Android 7.0 (Keymaster 2) dan pengesahan ID di Android 8.0 (Keymaster 3).
Pengesahan kunci bertujuan untuk memberikan cara guna menentukan dengan kuat apakah pasangan kunci asimetris didukung hardware, apa properti kunci tersebut, dan batasan apa yang diterapkan pada penggunaannya.
Pengesahan ID memungkinkan perangkat memberikan bukti ID hardware-nya, seperti nomor seri atau IMEI.
Pengesahan kunci
Untuk mendukung pengesahan kunci, Android 7.0 memperkenalkan serangkaian tag, jenis, dan metode ke HAL.
Tag
Tag::ATTESTATION_CHALLENGE
Tag::INCLUDE_UNIQUE_ID
Tag::RESET_SINCE_ID_ROTATION
Jenis
Keymaster 2 dan yang lebih lama
typedef struct { keymaster_blob_t* entries; size_t entry_count; } keymaster_cert_chain_t;
Metode AttestKey
Keymaster 3
attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams) generates(ErrorCode error, vec<vec<uint8_t>> certChain);
Keymaster 2 dan yang lebih lama
keymaster_error_t (*attest_key)(const struct keymaster2_device* dev, const keymaster_key_blob_t* key_to_attest, const keymaster_key_param_set_t* attest_params, keymaster_cert_chain_t* cert_chain);
dev
adalah struktur perangkat keymaster.keyToAttest
adalah blob kunci yang ditampilkan darigenerateKey
yang pembuatan pengesahannya.attestParams
adalah daftar parameter yang diperlukan untuk pengesahan. Hal ini mencakupTag::ATTESTATION_CHALLENGE
dan mungkinTag::RESET_SINCE_ID_ROTATION
, sertaTag::APPLICATION_ID
danTag::APPLICATION_DATA
. Dua yang terakhir diperlukan untuk mendekripsi blob kunci jika ditentukan selama pembuatan kunci.certChain
adalah parameter output, yang menampilkan array sertifikat. Entri 0 adalah sertifikat pengesahan, yang berarti mengesahkan kunci darikeyToAttest
dan berisi ekstensi pengesahan.
Metode attestKey
dianggap sebagai operasi kunci publik pada
kunci yang diautentikasi, karena dapat dipanggil kapan saja dan tidak perlu memenuhi
batasan otorisasi. Misalnya, jika kunci yang diautentikasi memerlukan autentikasi
pengguna untuk digunakan, pengesahan dapat dibuat tanpa autentikasi
pengguna.
Sertifikat pengesahan
Sertifikat pengesahan adalah sertifikat X.509 standar, dengan ekstensi pengesahan opsional yang berisi deskripsi kunci yang diautentikasi. Sertifikat ditandatangani dengan kunci pengesahan bersertifikasi. Kunci pengesahan mungkin menggunakan algoritma yang berbeda dari kunci yang disahkan.
Sertifikat pengesahan berisi kolom dalam tabel di bawah dan tidak boleh berisi kolom tambahan apa pun. Beberapa kolom menentukan nilai kolom tetap. Pengujian CTS memvalidasi bahwa konten sertifikat sama persis dengan yang ditentukan.
SEQUENCE Sertifikat
Nama kolom (lihat RFC 5280) | Nilai |
---|---|
tbsCertificate | URUTAN TBSCertificate |
signatureAlgorithm | AlgorithmIdentifier algoritma yang digunakan untuk menandatangani kunci: ECDSA untuk kunci EC, RSA untuk kunci RSA. |
signatureValue | BIT STRING, tanda tangan yang dihitung pada tbsCertificate yang dienkode DER ASN.1. |
SEQUENCE TBSCertificate
Nama kolom (lihat RFC 5280) | Nilai |
---|---|
version |
INTEGER 2 (berarti sertifikat v3) |
serialNumber |
INTEGER 1 (nilai tetap: sama di semua sertifikat) |
signature |
AlgorithmIdentifier algoritma yang digunakan untuk menandatangani kunci: ECDSA untuk kunci EC, RSA untuk kunci RSA. |
issuer |
Sama dengan kolom subjek kunci pengesahan batch. |
validity |
SEQUENCE dua tanggal, yang berisi nilai
Tag::ACTIVE_DATETIME dan
Tag::USAGE_EXPIRE_DATETIME.
Nilai tersebut dalam milidetik sejak 1 Januari 1970.
Lihat RFC 5280 untuk representasi tanggal yang benar dalam sertifikat. Jika Tag::ACTIVE_DATETIME tidak ada, gunakan nilai
Tag::CREATION_DATETIME . Jika
Tag::USAGE_EXPIRE_DATETIME tidak ada, gunakan tanggal habis masa berlaku
sertifikat kunci pengesahan batch. |
subject |
CN = "Android Keystore Key" (nilai tetap: sama di semua sertifikat) |
subjectPublicKeyInfo |
SubjectPublicKeyInfo yang berisi kunci publik yang dibuktikan. |
extensions/Key Usage |
digitalSignature: disetel jika kunci memiliki tujuan KeyPurpose::SIGN atau
KeyPurpose::VERIFY . Semua bit lainnya tidak disetel. |
extensions/CRL Distribution Points |
Nilai Ditentukan Nanti |
extensions/"attestation" |
OID-nya adalah 1.3.6.1.4.1.11129.2.1.17; kontennya ditentukan dalam bagian Ekstensi Pengesahan di bawah. Seperti semua ekstensi sertifikat X.509, konten direpresentasikan sebagai OCTET_STRING yang berisi encoding DER dari SEQUENCE pengesahan. |
Ekstensi pengesahan
Ekstensi attestation
berisi deskripsi lengkap otorisasi keymaster
yang terkait dengan kunci, dalam struktur yang secara langsung sesuai
dengan daftar otorisasi seperti yang digunakan di Android dan HAL keymaster. Setiap tag dalam
daftar otorisasi diwakili oleh entri ASN.1 SEQUENCE
, yang secara eksplisit
diberi tag dengan nomor tag keymaster, tetapi dengan deskripsi jenis (empat bit
urutan tinggi) yang disamarkan.
Misalnya, di Keymaster 3, Tag::PURPOSE
ditentukan dalam
types.hal sebagai ENUM_REP | 1
. Untuk ekstensi pengesahan,
nilai ENUM_REP
dihapus, sehingga tag 1
tetap ada.
(Untuk Keymaster 2 dan yang lebih lama, KM_TAG_PURPOSE
ditentukan dalam
keymaster_defs.h.)
Nilai diterjemahkan dengan cara yang mudah ke jenis ASN.1, per tabel ini:
Jenis Keymaster | Jenis ASN.1 |
---|---|
ENUM |
BILANGAN BULAT |
ENUM_REP |
SET of INTEGER |
UINT |
BILANGAN BULAT |
UINT_REP |
SET of INTEGER |
ULONG |
BILANGAN BULAT |
ULONG_REP |
SET of INTEGER |
DATE |
INTEGER (milidetik sejak 1 Januari 1970 00.00.00 GMT) |
BOOL |
NULL (di keymaster, tag ada berarti benar, tidak ada berarti salah. Semantik yang sama berlaku untuk encoding ASN.1) |
BIGNUM |
Saat ini tidak digunakan, sehingga tidak ada pemetaan yang ditentukan |
BYTES |
OCTET_STRING |
Skema
Konten ekstensi pengesahan dijelaskan oleh skema ASN.1 berikut.
Versi 300
KeyDescription ::= SEQUENCE { attestationVersion 300, attestationSecurityLevel SecurityLevel, keyMintVersion INTEGER, keyMintSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), StrongBox (2), } AuthorizationList ::= SEQUENCE { purpose [1] EXPLICIT SET OF INTEGER OPTIONAL, algorithm [2] EXPLICIT INTEGER OPTIONAL, keySize [3] EXPLICIT INTEGER OPTIONAL, digest [5] EXPLICIT SET OF INTEGER OPTIONAL, padding [6] EXPLICIT SET OF INTEGER OPTIONAL, ecCurve [10] EXPLICIT INTEGER OPTIONAL, rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL, mgfDigest [203] EXPLICIT SET OF INTEGER OPTIONAL, rollbackResistance [303] EXPLICIT NULL OPTIONAL, earlyBootOnly [305] EXPLICIT NULL OPTIONAL, activeDateTime [400] EXPLICIT INTEGER OPTIONAL, originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, usageCountLimit [405] EXPLICIT INTEGER OPTIONAL, noAuthRequired [503] EXPLICIT NULL OPTIONAL, userAuthType [504] EXPLICIT INTEGER OPTIONAL, authTimeout [505] EXPLICIT INTEGER OPTIONAL, allowWhileOnBody [506] EXPLICIT NULL OPTIONAL, trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, deviceUniqueAttestation [720] EXPLICIT NULL OPTIONAL, attestationIdSecondImei [723] EXPLICIT OCTET_STRING OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
Versi 200
KeyDescription ::= SEQUENCE { attestationVersion 200, attestationSecurityLevel SecurityLevel, keyMintVersion INTEGER, keyMintSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), StrongBox (2), } AuthorizationList ::= SEQUENCE { purpose [1] EXPLICIT SET OF INTEGER OPTIONAL, algorithm [2] EXPLICIT INTEGER OPTIONAL, keySize [3] EXPLICIT INTEGER OPTIONAL, digest [5] EXPLICIT SET OF INTEGER OPTIONAL, padding [6] EXPLICIT SET OF INTEGER OPTIONAL, ecCurve [10] EXPLICIT INTEGER OPTIONAL, rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL, mgfDigest [203] EXPLICIT SET OF INTEGER OPTIONAL, rollbackResistance [303] EXPLICIT NULL OPTIONAL, earlyBootOnly [305] EXPLICIT NULL OPTIONAL, activeDateTime [400] EXPLICIT INTEGER OPTIONAL, originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, usageCountLimit [405] EXPLICIT INTEGER OPTIONAL, noAuthRequired [503] EXPLICIT NULL OPTIONAL, userAuthType [504] EXPLICIT INTEGER OPTIONAL, authTimeout [505] EXPLICIT INTEGER OPTIONAL, allowWhileOnBody [506] EXPLICIT NULL OPTIONAL, trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, deviceUniqueAttestation [720] EXPLICIT NULL OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
Versi 100
KeyDescription ::= SEQUENCE { attestationVersion 100, attestationSecurityLevel SecurityLevel, keyMintVersion INTEGER, keyMintSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), StrongBox (2), } AuthorizationList ::= SEQUENCE { purpose [1] EXPLICIT SET OF INTEGER OPTIONAL, algorithm [2] EXPLICIT INTEGER OPTIONAL, keySize [3] EXPLICIT INTEGER OPTIONAL, digest [5] EXPLICIT SET OF INTEGER OPTIONAL, padding [6] EXPLICIT SET OF INTEGER OPTIONAL, ecCurve [10] EXPLICIT INTEGER OPTIONAL, rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL, mgfDigest [203] EXPLICIT SET OF INTEGER OPTIONAL, rollbackResistance [303] EXPLICIT NULL OPTIONAL, earlyBootOnly [305] EXPLICIT NULL OPTIONAL, activeDateTime [400] EXPLICIT INTEGER OPTIONAL, originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, usageCountLimit [405] EXPLICIT INTEGER OPTIONAL, noAuthRequired [503] EXPLICIT NULL OPTIONAL, userAuthType [504] EXPLICIT INTEGER OPTIONAL, authTimeout [505] EXPLICIT INTEGER OPTIONAL, allowWhileOnBody [506] EXPLICIT NULL OPTIONAL, trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, deviceUniqueAttestation [720] EXPLICIT NULL OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
Versi 4
KeyDescription ::= SEQUENCE { attestationVersion 4, attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), StrongBox (2), } AuthorizationList ::= SEQUENCE { purpose [1] EXPLICIT SET OF INTEGER OPTIONAL, algorithm [2] EXPLICIT INTEGER OPTIONAL, keySize [3] EXPLICIT INTEGER OPTIONAL, digest [5] EXPLICIT SET OF INTEGER OPTIONAL, padding [6] EXPLICIT SET OF INTEGER OPTIONAL, ecCurve [10] EXPLICIT INTEGER OPTIONAL, rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL, rollbackResistance [303] EXPLICIT NULL OPTIONAL, earlyBootOnly [305] EXPLICIT NULL OPTIONAL, activeDateTime [400] EXPLICIT INTEGER OPTIONAL, originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, noAuthRequired [503] EXPLICIT NULL OPTIONAL, userAuthType [504] EXPLICIT INTEGER OPTIONAL, authTimeout [505] EXPLICIT INTEGER OPTIONAL, allowWhileOnBody [506] EXPLICIT NULL OPTIONAL, trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, allApplications [600] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, deviceUniqueAttestation [720] EXPLICIT NULL OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
Versi 3
KeyDescription ::= SEQUENCE { attestationVersion 3, attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), StrongBox (2), } AuthorizationList ::= SEQUENCE { purpose [1] EXPLICIT SET OF INTEGER OPTIONAL, algorithm [2] EXPLICIT INTEGER OPTIONAL, keySize [3] EXPLICIT INTEGER OPTIONAL, digest [5] EXPLICIT SET OF INTEGER OPTIONAL, padding [6] EXPLICIT SET OF INTEGER OPTIONAL, ecCurve [10] EXPLICIT INTEGER OPTIONAL, rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL, rollbackResistance [303] EXPLICIT NULL OPTIONAL, activeDateTime [400] EXPLICIT INTEGER OPTIONAL, originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, noAuthRequired [503] EXPLICIT NULL OPTIONAL, userAuthType [504] EXPLICIT INTEGER OPTIONAL, authTimeout [505] EXPLICIT INTEGER OPTIONAL, allowWhileOnBody [506] EXPLICIT NULL OPTIONAL, trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, allApplications [600] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
Versi 2
KeyDescription ::= SEQUENCE { attestationVersion 2, attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), } AuthorizationList ::= SEQUENCE { purpose [1] EXPLICIT SET OF INTEGER OPTIONAL, algorithm [2] EXPLICIT INTEGER OPTIONAL, keySize [3] EXPLICIT INTEGER OPTIONAL, digest [5] EXPLICIT SET OF INTEGER OPTIONAL, padding [6] EXPLICIT SET OF INTEGER OPTIONAL, ecCurve [10] EXPLICIT INTEGER OPTIONAL, rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL, activeDateTime [400] EXPLICIT INTEGER OPTIONAL, originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, noAuthRequired [503] EXPLICIT NULL OPTIONAL, userAuthType [504] EXPLICIT INTEGER OPTIONAL, authTimeout [505] EXPLICIT INTEGER OPTIONAL, allowWhileOnBody [506] EXPLICIT NULL OPTIONAL, allApplications [600] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rollbackResistant [703] EXPLICIT NULL OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
Versi 1
KeyDescription ::= SEQUENCE { attestationVersion 1, attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), } AuthorizationList ::= SEQUENCE { purpose [1] EXPLICIT SET OF INTEGER OPTIONAL, algorithm [2] EXPLICIT INTEGER OPTIONAL, keySize [3] EXPLICIT INTEGER OPTIONAL, digest [5] EXPLICIT SET OF INTEGER OPTIONAL, padding [6] EXPLICIT SET OF INTEGER OPTIONAL, ecCurve [10] EXPLICIT INTEGER OPTIONAL, rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL, activeDateTime [400] EXPLICIT INTEGER OPTIONAL, originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, noAuthRequired [503] EXPLICIT NULL OPTIONAL, userAuthType [504] EXPLICIT INTEGER OPTIONAL, authTimeout [505] EXPLICIT INTEGER OPTIONAL, allowWhileOnBody [506] EXPLICIT NULL OPTIONAL, allApplications [600] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rollbackResistant [703] EXPLICIT NULL OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
Kolom KeyDescription
Kolom keymasterVersion
dan attestationChallenge
diidentifikasi secara
posisional, bukan berdasarkan tag, sehingga tag dalam bentuk yang dienkode hanya menentukan
jenis kolom. Kolom lainnya secara implisit diberi tag seperti yang ditentukan dalam
skema.
Nama kolom | Jenis | Nilai |
---|---|---|
attestationVersion |
BILANGAN BULAT | Versi skema pengesahan: 1, 2, atau 3. |
attestationSecurity |
SecurityLevel | Tingkat keamanan pengesahan ini. Anda bisa mendapatkan pengesahan software kunci yang didukung hardware. Pengesahan tersebut tidak dapat dipercaya jika sistem Android disusupi. |
keymasterVersion |
BILANGAN BULAT | Versi perangkat keymaster: 0, 1, 2, 3, atau 4. |
keymasterSecurity |
SecurityLevel | Tingkat keamanan implementasi keymaster. |
attestationChallenge |
OKTET_STRING | Nilai Tag::ATTESTATION_CHALLENGE , ditetapkan ke permintaan pengesahan. |
uniqueId |
OKTET_STRING | ID unik opsional, ada jika kunci memiliki
Tag::INCLUDE_UNIQUE_ID |
softwareEnforced |
AuthorizationList | Opsional, otorisasi keymaster yang tidak diberlakukan oleh TEE, jika ada. |
teeEnforced |
AuthorizationList | Opsional, otorisasi Keymaster yang diberlakukan oleh TEE, jika ada. |
Kolom AuthorizationList
Semua kolom AuthorizationList
bersifat opsional dan diidentifikasi
oleh nilai tag keymaster, dengan bit jenis disamarkan.
Pemberian tag eksplisit digunakan agar kolom juga berisi tag yang menunjukkan jenis ASN.1-nya agar lebih mudah diuraikan.
Untuk mengetahui detail tentang nilai setiap kolom, lihat types.hal
untuk Keymaster 3 dan
keymaster_defs.h
untuk Keymaster 2 dan yang lebih lama. Nama tag Keymaster
diubah menjadi nama kolom dengan menghapus awalan KM_TAG
dan mengubah
sisanya menjadi camel case, sehingga Tag::KEY_SIZE
menjadi
keySize
.
Kolom RootOfTrust
Kolom RootOfTrust
diidentifikasi secara posisional.
Nama kolom | Jenis | Nilai |
---|---|---|
verifiedBootKey |
OCTET_STRING | Hash aman dari kunci yang digunakan untuk memverifikasi image sistem. SHA-256 direkomendasikan. |
deviceLocked |
BOOLEAN | Benar jika bootloader terkunci, yang berarti hanya image yang ditandatangani yang dapat di-flash, dan pemeriksaan booting terverifikasi telah dilakukan. |
verifiedBootState |
VerifiedBootState | Status booting terverifikasi. |
verifiedBootHash |
OCTET_STRING | Ringkasan semua data yang dilindungi oleh Booting Terverifikasi. Untuk perangkat yang menggunakan implementasi Booting Terverifikasi Android, nilai ini berisi ringkasan VBMeta struct, atau struktur metadata Booting Terverifikasi. Untuk mempelajari lebih lanjut cara menghitung nilai ini, lihat The VBMeta Digest |
Nilai VerifiedBootState
Nilai verifiedBootState
memiliki arti berikut:
Nilai | Arti |
---|---|
Verified |
Menunjukkan rantai kepercayaan lengkap yang meluas dari bootloader ke
partisi terverifikasi, termasuk bootloader, partisi booting, dan semua
partisi terverifikasi. Dalam status ini, nilai verifiedBootKey adalah hash sertifikat
yang disematkan, yang berarti sertifikat yang tidak dapat diubah di-burn ke ROM.Status ini sesuai dengan status booting hijau seperti yang didokumentasikan dalam dokumentasi alur booting terverifikasi. |
SelfSigned |
Menunjukkan bahwa partisi booting telah diverifikasi menggunakan sertifikat
yang disematkan, dan tanda tangan tersebut valid. Bootloader menampilkan peringatan dan
sidik jari kunci publik sebelum mengizinkan proses booting dilanjutkan.
Dalam status ini, nilai verifiedBootKey adalah hash sertifikat
yang ditandatangani sendiri.Status ini sesuai dengan status booting kuning seperti yang didokumentasikan dalam dokumentasi alur booting terverifikasi. |
Unverified |
Menunjukkan bahwa perangkat dapat diubah secara bebas. Integritas perangkat diserahkan kepada
pengguna untuk diverifikasi secara out-of-band. Bootloader menampilkan peringatan kepada pengguna
sebelum mengizinkan proses booting dilanjutkan. Dalam status ini, nilai verifiedBootKey kosong.Status ini sesuai dengan status booting oranye seperti yang didokumentasikan dalam dokumentasi alur booting terverifikasi. |
Failed |
Menunjukkan bahwa perangkat gagal diverifikasi. Tidak ada sertifikat pengesahan
yang benar-benar berisi nilai ini, karena dalam status ini bootloader akan berhenti. Ini
disertakan di sini untuk kelengkapan. Status ini sesuai dengan status booting merah seperti yang didokumentasikan dalam dokumentasi alur booting terverifikasi. |
Nilai SecurityLevel
Nilai securityLevel
memiliki arti berikut:
Nilai | Arti |
---|---|
Software |
Kode yang membuat atau mengelola elemen yang relevan (pengesahan atau kunci) diterapkan di sistem Android dan dapat diubah jika sistem tersebut disusupi. |
TrustedEnvironment |
Kode yang membuat atau mengelola elemen yang relevan (pengesahan atau kunci) diimplementasikan dalam Trusted Execution Environment (TEE). Kunci ini dapat diubah jika TEE disusupi, tetapi TEE sangat tahan terhadap penyusupan jarak jauh dan cukup tahan terhadap penyusupan oleh serangan hardware langsung. |
StrongBox |
Kode yang membuat atau mengelola elemen yang relevan (pernyataan autentikasi atau kunci) diterapkan dalam modul keamanan hardware khusus. Kunci ini dapat diubah jika modul keamanan hardware disusupi, tetapi sangat tahan terhadap penyusupan jarak jauh dan sangat tahan terhadap penyusupan oleh serangan hardware langsung. |
ID unik
ID Unik adalah nilai 128-bit yang mengidentifikasi perangkat, tetapi hanya selama jangka waktu terbatas. Nilai dihitung dengan:
HMAC_SHA256(T || C || R, HBK)
Dalam hal ini:
T
adalah "nilai penghitung temporal", yang dihitung dengan membagi nilaiTag::CREATION_DATETIME
dengan 2592000000, dengan menghapus sisanya.T
berubah setiap 30 hari (2592000000 = 30 * 24 * 60 * 60 * 1.000).C
adalah nilaiTag::APPLICATION_ID
R
adalah 1 jikaTag::RESET_SINCE_ID_ROTATION
ada dalam parameter attest_params ke panggilan attest_key, atau 0 jika tag tidak ada.HBK
adalah rahasia unik yang terikat hardware yang diketahui oleh Trusted Execution Environment dan tidak pernah diungkapkan olehnya. Secret berisi setidaknya 128 bit entropi dan unik untuk setiap perangkat (keunikan probabilistik dapat diterima mengingat 128 bit entropi). HBK harus berasal dari materi kunci gabungan melalui HMAC atau AES_CMAC.
Memotong output HMAC_SHA256 menjadi 128 bit.
Kunci dan sertifikat pengesahan
Dua kunci, satu RSA dan satu ECDSA, serta rantai sertifikat terkait, disediakan dengan aman ke dalam perangkat.
Android 12 memperkenalkan Penyediaan Kunci Jarak Jauh, dan Android 13 mewajibkan perangkat menerapkan fitur ini. Penyediaan Kunci Jarak Jauh menyediakan sertifikat pengesahan ECDSA P256 per aplikasi untuk perangkat di lapangan. Masa berlaku sertifikat ini lebih singkat daripada sertifikat yang disediakan oleh pabrik.
Beberapa IMEI
Android 14 menambahkan dukungan untuk beberapa IMEI dalam data Pengesahan Kunci Android. OEM dapat menerapkan fitur ini dengan menambahkan tag KeyMint untuk IMEI kedua. Perangkat yang memiliki beberapa radio seluler kini semakin umum, dan OEM kini dapat mendukung perangkat dengan dua IMEI.
OEM wajib memiliki IMEI sekunder, jika ada di perangkat mereka, untuk disediakan untuk implementasi KeyMint sehingga implementasi tersebut dapat mengesahkannya dengan cara yang sama seperti saat mengesahkan IMEI pertama
Pengesahan ID
Android 8.0 menyertakan dukungan opsional untuk pengesahan ID untuk perangkat dengan Keymaster 3. Pengesahan ID memungkinkan perangkat memberikan bukti ID hardware-nya, seperti nomor seri atau IMEI. Meskipun merupakan fitur opsional, sebaiknya semua implementasi Keymaster 3 memberikan dukungan untuknya karena dapat membuktikan identitas perangkat memungkinkan kasus penggunaan seperti konfigurasi jarak jauh zero-touch yang sebenarnya menjadi lebih aman (karena sisi jarak jauh dapat yakin bahwa perangkat tersebut terhubung ke perangkat yang tepat, bukan perangkat yang melakukan spoofing identitas).
Pengesahan ID berfungsi dengan membuat salinan ID hardware perangkat yang hanya dapat diakses oleh Trusted Execution Environment (TEE) sebelum perangkat keluar dari pabrik. Pengguna dapat membuka kunci bootloader perangkat dan mengubah software sistem serta ID yang dilaporkan oleh framework Android. Salinan ID yang disimpan oleh TEE tidak dapat dimanipulasi dengan cara ini, sehingga memastikan bahwa pengesahan ID perangkat hanya mengesahkan ID hardware asli perangkat, sehingga menggagalkan upaya spoofing.
Platform API utama untuk pengesahan ID dibuat berdasarkan mekanisme pengesahan kunci yang ada dan diperkenalkan dengan Keymaster 2. Saat meminta sertifikat pengesahan untuk kunci yang disimpan oleh keymaster, pemanggil dapat meminta ID hardware perangkat disertakan dalam metadata sertifikat pengesahan. Jika kunci disimpan di TEE, sertifikat akan dirantai kembali ke root kepercayaan yang diketahui. Penerima sertifikat tersebut dapat memverifikasi bahwa sertifikat dan kontennya, termasuk ID hardware, ditulis oleh TEE. Saat diminta untuk menyertakan ID hardware dalam sertifikat pengesahan, TEE hanya membuktikan ID yang disimpan di penyimpanannya, seperti yang diisi di lantai pabrik.
Properti penyimpanan
Penyimpanan yang menyimpan ID perangkat harus memiliki properti berikut:
- Nilai yang berasal dari ID asli perangkat disalin ke penyimpanan sebelum perangkat keluar dari pabrik.
- Metode
destroyAttestationIds()
dapat menghancurkan salinan data turunan ID ini secara permanen. Penghancuran permanen berarti data dihapus sepenuhnya sehingga reset pabrik atau prosedur lain yang dilakukan pada perangkat tidak dapat memulihkannya. Hal ini sangat penting untuk perangkat yang penggunanya telah membuka kunci bootloader dan mengubah software sistem serta memodifikasi ID yang ditampilkan oleh framework Android. - Fasilitas RMA harus memiliki kemampuan untuk membuat salinan baru data yang berasal dari ID hardware. Dengan cara ini, perangkat yang melewati RMA dapat melakukan pengesahan ID lagi. Mekanisme yang digunakan oleh fasilitas RMA harus dilindungi agar pengguna tidak dapat memanggilnya sendiri, karena hal itu akan memungkinkan mereka mendapatkan pengesahan ID yang di-spoof.
- Tidak ada kode selain aplikasi tepercaya Keymaster di TEE yang dapat membaca data turunan ID yang disimpan di penyimpanan.
- Penyimpanan tidak dapat dirusak: Jika konten penyimpanan telah diubah, TEE akan memperlakukannya sama seperti salinan konten telah dihancurkan dan menolak semua upaya pengesahan ID. Hal ini diimplementasikan dengan menandatangani atau membuat MAC penyimpanan seperti yang dijelaskan di bawah.
- Penyimpanan tidak menyimpan ID asli. Karena pengesahan ID melibatkan sebuah tantangan, pemanggil selalu menyediakan ID yang akan disahkan. TEE hanya perlu memverifikasi bahwa nilai tersebut cocok dengan nilai yang awalnya dimiliki. Menyimpan hash yang aman dari nilai asli, bukan nilainya, akan memungkinkan verifikasi ini.
Konstruksi
Untuk membuat implementasi yang memiliki properti yang tercantum di atas, simpan nilai turunan ID dalam konstruksi S berikut. Jangan simpan salinan lain nilai ID, kecuali tempat normal dalam sistem, yang dapat diubah oleh pemilik perangkat dengan melakukan root:
S = D || HMAC(HBK, D)
dalam hal ini:
D = HMAC(HBK, ID1) || HMAC(HBK, ID2) || ... || HMAC(HBK, IDn)
HMAC
adalah konstruksi HMAC dengan hash aman yang sesuai (SHA-256 direkomendasikan)HBK
adalah kunci yang terikat dengan hardware dan tidak digunakan untuk tujuan lainID1...IDn
adalah nilai ID asli; pengaitan nilai tertentu ke indeks tertentu bergantung pada implementasi, karena perangkat yang berbeda memiliki jumlah ID yang berbeda||
mewakili penyambungan
Karena output HMAC memiliki ukuran tetap, tidak ada header atau struktur lain yang diperlukan untuk dapat menemukan hash ID individual, atau HMAC D. Selain memeriksa nilai yang diberikan untuk melakukan pengesahan, implementasi perlu memvalidasi S dengan mengekstrak D dari S, menghitung HMAC(HBK, D), dan membandingkannya dengan nilai di S untuk memverifikasi bahwa tidak ada ID individual yang dimodifikasi/rusak. Selain itu, implementasi harus menggunakan perbandingan waktu konstan untuk setiap elemen ID dan validasi S. Waktu perbandingan harus konstan, terlepas dari jumlah ID yang diberikan dan pencocokan yang benar dari bagian pengujian mana pun.
Pengidentifikasi hardware
Pengesahan ID mendukung ID hardware berikut:
- Nama merek, seperti yang ditampilkan oleh
Build.BRAND
di Android - Nama perangkat, seperti yang ditampilkan oleh
Build.DEVICE
di Android - Nama produk, seperti yang ditampilkan oleh
Build.PRODUCT
di Android - Nama produsen, seperti yang ditampilkan oleh
Build.MANUFACTURER
di Android - Nama model, seperti yang ditampilkan oleh
Build.MODEL
di Android - Nomor seri
- IMEI semua radio
- MEID semua radio
Untuk mendukung pengesahan ID perangkat, perangkat mengesahkan ID ini. Semua perangkat yang menjalankan Android memiliki enam yang pertama dan diperlukan agar fitur ini berfungsi. Jika perangkat memiliki radio seluler terintegrasi, perangkat juga harus mendukung pengesahan untuk IMEI dan/atau MEID radio.
Pengesahan ID diminta dengan melakukan pengesahan kunci dan menyertakan ID perangkat untuk dibuktikan dalam permintaan. ID diberi tag sebagai:
ATTESTATION_ID_BRAND
ATTESTATION_ID_DEVICE
ATTESTATION_ID_PRODUCT
ATTESTATION_ID_MANUFACTURER
ATTESTATION_ID_MODEL
ATTESTATION_ID_SERIAL
ATTESTATION_ID_IMEI
ATTESTATION_ID_MEID
ID yang akan dibuktikan adalah string byte berenkode UTF-8. Format ini juga berlaku untuk ID numerik. Setiap ID yang akan dibuktikan dinyatakan sebagai string yang dienkode UTF-8.
Jika perangkat tidak mendukung pengesahan ID (atau
destroyAttestationIds()
sebelumnya dipanggil dan perangkat tidak dapat
lagi membuktikan ID-nya), setiap permintaan pengesahan kunci yang menyertakan satu atau beberapa
tag ini akan gagal dengan ErrorCode::CANNOT_ATTEST_IDS
.
Jika perangkat mendukung pengesahan ID dan satu atau beberapa tag di atas telah
disertakan dalam permintaan pengesahan kunci, TEE akan memverifikasi ID
yang diberikan dengan setiap tag cocok dengan salinan ID hardware-nya. Jika
satu atau beberapa ID tidak cocok, seluruh pengesahan akan gagal dengan
ErrorCode::CANNOT_ATTEST_IDS
. Tag yang sama dapat
disediakan beberapa kali. Hal ini dapat berguna, misalnya, saat membuktikan IMEI:
Perangkat dapat memiliki beberapa radio dengan beberapa IMEI. Permintaan pengesahan
valid jika nilai yang diberikan dengan setiap ATTESTATION_ID_IMEI
cocok
dengan salah satu radio perangkat. Hal yang sama berlaku untuk semua tag lainnya.
Jika pengesahan berhasil, ID yang disahkan akan ditambahkan ke ekstensi pengesahan (OID 1.3.6.1.4.1.11129.2.1.17) dari sertifikat pengesahan yang dikeluarkan, menggunakan skema dari atas. Perubahan dari skema pengesahan Keymaster 2 akan dicetak tebal, dengan komentar.
Java API
Bagian ini hanya berfungsi sebagai informasi. Implementer Keymaster tidak menerapkan atau menggunakan Java API. Informasi ini diberikan untuk membantu pengimplementasi memahami cara fitur ini digunakan oleh aplikasi. Komponen sistem mungkin menggunakannya secara berbeda, itulah sebabnya bagian ini harus tidak dianggap normatif.