Keystore to bezpieczniejsze miejsce do tworzenia, przechowywania i używania kluczy kryptograficznych w kontrolowany sposób. Gdy dostępne jest miejsce na klucze obsługiwane sprzętowo i jest ono używane, materiały klucza są lepiej chronione przed wydobyciem z urządzenia, a Keymaster nakłada ograniczenia, które trudno jest obejść.
Jest to jednak możliwe tylko wtedy, gdy wiadomo, że klucze magazynu kluczy znajdują się w pamięci obsługiwanej przez sprzęt. W Keymaster 1 aplikacje ani serwery zdalne nie miały możliwości dokładnego sprawdzenia, czy tak jest. Demon klucza załadował dostępne interfejsy HAL klucza głównego i uwierzył w to, cokolwiek powiedział interfejs HAL na temat sprzętowego zabezpieczenia kluczy.
Aby to naprawić, wprowadziliśmy w Androidzie 7.0 (Keymaster 2) weryfikację klucza, a w Androidzie 8.0 (Keymaster 3) – weryfikację tożsamości.
Potwierdzenie klucza ma na celu zapewnienie możliwości dokładnego określenia, czy para kluczy asymetrycznych jest obsługiwana przez sprzęt, jakie są właściwości klucza i jakie ograniczenia dotyczą jego użycia.
Potwierdzenie tożsamości umożliwia urządzeniu przedstawienie dowodu tożsamości identyfikatorów sprzętowych, takich jak numer seryjny lub IMEI.
Atestacja klucza
Aby obsługiwać uwierzytelnianie klucza, w Androidzie 7.0 wprowadzono do HAL zestaw tagów, typów i metod.
Tagi
Tag::ATTESTATION_CHALLENGE
Tag::INCLUDE_UNIQUE_ID
Tag::RESET_SINCE_ID_ROTATION
Typ
Keymaster 2 i starsze
typedef struct { keymaster_blob_t* entries; size_t entry_count; } keymaster_cert_chain_t;
Metoda AttestKey
Keymaster 3
attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams) generates(ErrorCode error, vec<vec<uint8_t>> certChain);
Keymaster 2 i starsze
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
to struktura urządzenia Keymaster.keyToAttest
to klucz blob zwrócony zgenerateKey
, dla którego tworzony jest atest.attestParams
to lista parametrów niezbędnych do uwierzytelnienia. Obejmuje toTag::ATTESTATION_CHALLENGE
i opcjonalnieTag::RESET_SINCE_ID_ROTATION
, a takżeTag::APPLICATION_ID
iTag::APPLICATION_DATA
. Te 2 ostatnie są potrzebne do odszyfrowania klucza blob, jeśli zostały określone podczas generowania klucza.certChain
to parametr wyjściowy, który zwraca tablicę certyfikatów. Wpis 0 to certyfikat atestacji, czyli certyfikat klucza zkeyToAttest
, który zawiera rozszerzenie atestacji.
Metoda attestKey
jest uważana za operację klucza publicznego na zatwierdzonym kluczu, ponieważ można ją wywołać w dowolnym momencie i nie musi spełniać ograniczeń autoryzacji. Jeśli na przykład uwierzytelniony klucz wymaga uwierzytelnienia użytkownika, aby można było go użyć, uwierzytelnienie może zostać wygenerowane bez uwierzytelnienia użytkownika.
certyfikat atestacji,
Certyfikat atestu to standardowy certyfikat X.509 z opcjonalnym rozszerzeniem atestu, który zawiera opis atestowanego klucza. Certyfikat jest podpisany za pomocą certyfikowanego klucza uwierzytelniania. Klucz weryfikacji może używać innego algorytmu niż klucz weryfikowany.
Certyfikat zawiera pola widoczne w tabeli poniżej i nie może zawierać żadnych dodatkowych pól. Niektóre pola określają stałą wartość pola. Testy CTS sprawdzają, czy treść certyfikatu jest dokładnie taka, jak określono.
KOLEJNOŚĆ certyfikatów
Nazwa pola (patrz RFC 5280) | Wartość |
---|---|
tbsCertificate | TBSCertificate SEQUENCE |
signatureAlgorithm | Algorytm algorytmu używany do podpisywania klucza: ECDSA dla kluczy EC, RSA dla kluczy RSA. |
signatureValue | BIT STRING, podpis wyliczony na podstawie certyfikatu tbsCertificate z kodowaniem DER ASN.1. |
TBSCertificate SEQUENCE
Nazwa pola (patrz RFC 5280) | Wartość |
---|---|
version |
INTEGER 2 (oznacza certyfikat w wersji 3) |
serialNumber |
INTEGER 1 (wartość stała: taka sama w wszystkich certyfikatach) |
signature |
Algorytm algorytmu używany do podpisywania klucza: ECDSA dla kluczy EC, RSA dla kluczy RSA. |
issuer |
Taki sam jak pole tematu klucza atesta personalizacji zbiorczej. |
validity |
SEKWENCJA z 2 datami z wartościami Tag::ACTIVE_DATETIME i Tag:USAGE_disable_DATETIME.
Wartości są podawane w milisekundach od 1 stycznia 1970 r.
Informacje o poprawnym formatowaniu dat w certyfikatach znajdziesz w dokumentie RFC 5280. Jeśli Tag::ACTIVE_DATETIME nie ma, użyj wartości Tag::CREATION_DATETIME . Jeśli elementTag::USAGE_EXPIRE_DATETIME jest nieobecny, użyj daty wygaśnięcia certyfikatu klucza weryfikacji zbiorczej. |
subject |
CN = „Android Keystore Key” (wartość stała: taka sama dla wszystkich certyfikatów) |
subjectPublicKeyInfo |
SubjectPublicKeyInfo zawierający potwierdzony klucz publiczny. |
extensions/Key Usage |
cyfrowy podpis: ustaw, jeśli klucz ma przeznaczenie KeyPurpose::SIGN lub KeyPurpose::VERIFY . Pozostałe bity są puste. |
extensions/CRL Distribution Points |
Wartość do ustalenia |
extensions/"attestation" |
OID to 1.3.6.1.4.1.11129.2.1.17; treść jest zdefiniowana w sekcji Rozszerzenie certyfikatu poniżej. Podobnie jak w przypadku wszystkich rozszerzeń certyfikatu X.509, zawartość jest reprezentowana jako ciąg znaków OCTET_STRING zawierający kodowanie DER sekwencji atesta. |
Rozszerzenie atestacji
Rozszerzenie attestation
ma identyfikator OID1.3.6.1.4.1.11129.2.1.17
. Zawiera on informacje o akredytowanej parze kluczy i stanie urządzenia w momencie generowania klucza.
Typy tagów Keymaster/KeyMint zdefiniowane w specyfikacji interfejsu AIDL są tłumaczone na typy ASN.1 w następujący sposób:
Typ Keymaster/KeyMint | Typ ASN.1 | Uwagi |
---|---|---|
ENUM |
INTEGER |
|
ENUM_REP |
SET of INTEGER |
|
UINT |
INTEGER |
|
UINT_REP |
SET of INTEGER |
|
ULONG |
INTEGER |
|
ULONG_REP |
SET of INTEGER |
|
DATE |
INTEGER |
Milisekundy od 1 stycznia 1970 r., 00:00:00 GMT. |
BOOL |
NULL |
Obecność tagu oznacza wartość „prawda”, a „brak” – „fałsz”. |
BIGNUM |
Żaden tag nie ma tego typu, więc nie ma zdefiniowanego mapowania. | |
BYTES |
OCTET_STRING |
Schemat
Treść rozszerzenia atesta jest opisana za pomocą tego schematu ASN.1:
Wersja 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), }
Wersja 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), }
Wersja 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), }
Wersja 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), }
Wersja 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), }
Wersja 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), }
Wersja 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), }
Pola KeyDescription
-
attestationVersion
- Wersja schematu ASN.1.
Wartość Wersja Keymaster/KeyMint 1 Keymaster w wersji 2.0 2 Keymaster w wersji 3.0 3 Keymaster w wersji 4.0 4 Keymaster w wersji 4.1 100 KeyMint w wersji 1.0 200 KeyMint w wersji 2.0 300 KeyMint w wersji 3.0 -
attestationSecurityLevel
-
Poziom zabezpieczeń lokalizacji, w której przechowywany jest poświadczony klucz.
-
keymasterVersion
/keyMintVersion
- Wersja implementacji warstwy abstrakcji sprzętowej (HAL) Keymastera/KeyMinta.
Wartość Wersja Keymaster/KeyMint 2 Keymaster w wersji 2.0 3 Keymaster w wersji 3.0 4 Keymaster w wersji 4.0 41 Keymaster w wersji 4.1 100 KeyMint w wersji 1.0 200 KeyMint w wersji 2.0 300 KeyMint w wersji 3.0 -
keymasterSecurityLevel
/keyMintSecurityLevel
- Poziom bezpieczeństwa wdrożenia Keymaster/KeyMint.
-
attestationChallenge
- Wyzwanie podane w momencie generowania klucza.
-
uniqueId
- Identyfikator urządzenia uwzględniający prywatność, którego aplikacje systemowe mogą używać w momencie generowania kluczy. Jeśli nie jest wymagany identyfikator, to pole jest puste. Szczegółowe informacje znajdziesz w sekcji Unikalny identyfikator.
-
softwareEnforced
-
Kluczmaster/KeyMint
Lista autoryzacji, która jest egzekwowana przez system Android. Te informacje są zbierane lub generowane przez kod na platformie i przechowywane na partycji systemowej urządzenia. Urządzenie jest uznawane za zaufane, o ile działa na nim system operacyjny zgodny z modelem zabezpieczeń platformy Android (czyli program rozruchowy urządzenia jest zablokowany, a
verifiedBootState
jestVerified
). -
hardwareEnforced
- Lista autoryzacji Keymaster/KeyMint wymuszana przez zaufane środowisko wykonawcze TEE (Trusted Execution Environment) lub StrongBox urządzenia. Te informacje są zbierane lub generowane przez kod na bezpiecznym sprzęcie i nie są kontrolowane przez platformę. Informacje mogą na przykład pochodzić z programu rozruchowego lub z bezpiecznego kanału komunikacji, który nie wymaga zaufania do platformy.
Wartości SecurityLevel
Wartość SecurityLevel
wskazuje, w jakim stopniu element związany z Keystore (np. para kluczy i poświadczenie) jest odporny na ataki.
Wartość | Znaczenie |
---|---|
Software |
Bezpieczne, o ile system Androida na urządzeniu jest zgodny z modelem zabezpieczeń platformy Android (czyli program rozruchowy urządzenia jest zablokowany, a verifiedBootState Verified ). |
TrustedEnvironment |
Bezpieczeństwo jest zapewnione, o ile zaufane środowisko wykonawcze (TEE) nie zostanie naruszone. Wymagania dotyczące izolacji TEE są zdefiniowane w sekcjach 9.11 [C-1-1] do [C-1-4] dokumentu definicji zgodności Androida. TEE są wysoce odporne na zdalne naruszenie zabezpieczeń i umiarkowanie odporne na naruszenie zabezpieczeń przez bezpośredni atak sprzętowy. |
StrongBox |
Bezpieczne, o ile StrongBox nie zostanie naruszone. StrongBox jest implementowany w elementach zabezpieczeń podobnych do sprzętowego modułu zabezpieczeń. Wymagania dotyczące implementacji StrongBox są określone w sekcji 9.11.2 dokumentu definicji zgodności Androida. StrongBox jest wysoce odporny na zdalne naruszenie zabezpieczeń i bezpośrednie ataki sprzętowe (np. manipulację fizyczną i ataki kanału bocznego). |
Pola AuthorizationList
Każde pole odpowiada tagowi autoryzacji Keymaster/KeyMint z specyfikacji interfejsu AIDL.
Specyfikacja jest źródłem informacji o tagach autoryzacji: ich znaczeniu, formacie zawartości, oczekiwanym miejscu wyświetlania w polach softwareEnforced
lub hardwareEnforced
obiektu KeyDescription
, wzajemnym wykluczaniu się z innymi tagami itp. Wszystkie pola AuthorizationList
są opcjonalne.
Każde pole ma tag EXPLICIT
, który jest tagiem kontekstowym o wartości odpowiadającej numerowi tagu Keymaster/KeyMint. Umożliwia to bardziej zwartą reprezentację danych w AuthorizationList
. Dlatego parsujący ASN.1 musi znać oczekiwany typ danych dla każdego tagu kontekstowego. Na przykład:
Tag::USER_AUTH_TYPE
jest zdefiniowana jako ENUM | 504
. W schemacie rozszerzenia potwierdzenia pole purpose
w AuthorizationList
jest określone jako userAuthType [504] EXPLICIT INTEGER OPTIONAL
. Jego kodowanie ASN.1 będzie więc zawierać tag kontekstowy 504
zamiast tagu klasy UNIVERSAL
dla typu ASN.1 INTEGER
, który jest 10
.
-
purpose
-
Zgodnie z tagiem autoryzacji
Tag::PURPOSE
, który używa wartości identyfikatora tagu 1. -
algorithm
-
Odpowiada tagowi autoryzacji
Tag::ALGORITHM
, który ma identyfikator tagu równy 2.W obiekcie weryfikacji
AuthorizationList
wartość algorytmu jest zawszeRSA
lubEC
. -
keySize
-
Zgodnie z tagiem autoryzacji
Tag::KEY_SIZE
, który używa wartości identyfikatora tagu 3. -
digest
- Odpowiada tagowi autoryzacji
Tag::DIGEST
, który ma identyfikator tagu o wartości 5. -
padding
- Odpowiada tagowi autoryzacji
Tag::PADDING
, który korzysta z wartości identyfikatora tagu wynoszącej 6. -
ecCurve
-
Odpowiada tagowi autoryzacji
Tag::EC_CURVE
, który ma identyfikator tagu o wartości 10.Zbiór parametrów używanych do generowania pary kluczy krzywej eliptycznej (EC), która używa ECDSA do podpisywania i weryfikacji w magazynie kluczy systemu Android.
-
rsaPublicExponent
-
Zgodnie z tagiem autoryzacji
Tag::RSA_PUBLIC_EXPONENT
, który używa wartości identyfikatora tagu 200. -
mgfDigest
-
Występuje tylko w wersji atesta klucza >= 100.
Odpowiada tagowi autoryzacjiTag::RSA_OAEP_MGF_DIGEST
KeyMint, który używa wartości identyfikatora tagu 203. -
rollbackResistance
-
Dostępne tylko w wersji weryfikacji klucza ≥3.
Odpowiada tagowi autoryzacji
Tag::ROLLBACK_RESISTANCE
, który używa wartości identyfikatora tagu 303. -
earlyBootOnly
-
Prezentuje się tylko w wersji atestu klucza >= 4.
Odpowiada tagowi autoryzacji
Tag::EARLY_BOOT_ONLY
, który ma wartość identyfikatora tagu 305. -
activeDateTime
- Odpowiada tagowi autoryzacji
Tag::ACTIVE_DATETIME
, który ma identyfikator tagu o wartości 400. -
originationExpireDateTime
- Odpowiada tagowi autoryzacji
Tag::ORIGINATION_EXPIRE_DATETIME
Keymaster, który korzysta z wartości identyfikatora tagu 401. -
usageExpireDateTime
-
Zgodnie z tagiem autoryzacji
Tag::USAGE_EXPIRE_DATETIME
, który używa wartości identyfikatora tagu 402. -
usageCountLimit
-
Zgodny z tagiem autoryzacji
Tag::USAGE_COUNT_LIMIT
, który używa wartości identyfikatora tagu 405. -
noAuthRequired
-
Odpowiada tagowi autoryzacji
Tag::NO_AUTH_REQUIRED
, który używa wartości identyfikatora tagu 503. -
userAuthType
-
Zgodny z tagiem autoryzacji
Tag::USER_AUTH_TYPE
, który używa wartości identyfikatora tagu 504. -
authTimeout
- Odpowiada tagowi autoryzacji
Tag::AUTH_TIMEOUT
, który korzysta z wartości identyfikatora tagu 505. -
allowWhileOnBody
-
Odpowiada tagowi autoryzacji
Tag::ALLOW_WHILE_ON_BODY
, który ma wartość identyfikatora tagu 506.Zezwala na korzystanie z klucza po upłynięciu czasu uwierzytelniania, jeśli użytkownik nadal ma urządzenie przy sobie. Pamiętaj, że czujnik na ciele użytkownika określa, czy urządzenie jest noszone na ciele użytkownika.
-
trustedUserPresenceRequired
-
Dostępne tylko w wersji weryfikacji klucza ≥3.
Odpowiada tagowi autoryzacji
Tag::TRUSTED_USER_PRESENCE_REQUIRED
, który używa wartości identyfikatora tagu 507.Określa, że klucz można używać tylko wtedy, gdy użytkownik przedstawił dowód swojej fizycznej obecności. Oto kilka przykładów:
- W przypadku klucza StrongBox przycisk sprzętowy podłączony na stałe do pinezki na urządzeniu StrongBox.
- W przypadku klucza TEE uwierzytelnianie odciskiem palca zapewnia dowód obecności, o ile TEE ma wyłączną kontrolę nad skanerem i wykonuje proces dopasowywania odcisków palców.
-
trustedConfirmationRequired
-
Dostępne tylko w wersji weryfikacji klucza ≥3.
Odpowiada tagowi autoryzacji
Tag::TRUSTED_CONFIRMATION_REQUIRED
, który ma wartość identyfikatora tagu 508.Określa, że klucz jest dostępny tylko wtedy, gdy użytkownik potwierdzi dane, które mają zostać podpisane za pomocą tokena zatwierdzenia. Więcej informacji o tym, jak uzyskać potwierdzenie od użytkownika, znajdziesz w artykule Potwierdzanie za pomocą Androida.
Uwaga: ten tag ma zastosowanie tylko do kluczy o przeznaczeniu
SIGN
. -
unlockedDeviceRequired
-
Prezentuje się tylko w wersji atestu klucza >= 3.
Odpowiada tagowi autoryzacji
Tag::UNLOCKED_DEVICE_REQUIRED
, który używa wartości identyfikatora tagu 509. -
allApplications
-
Odpowiada tagowi autoryzacji
Tag::ALL_APPLICATIONS
, który używa wartości identyfikatora tagu 600.Wskazuje, czy wszystkie aplikacje na urządzeniu mają dostęp do pary kluczy.
-
applicationId
-
Zgodna z tagiem autoryzacji
Tag::APPLICATION_ID
, który używa wartości identyfikatora tagu 601. -
creationDateTime
-
Zgodny z tagiem autoryzacji
Tag::CREATION_DATETIME
, który używa wartości identyfikatora tagu 701. -
origin
-
Odpowiada tagowi autoryzacji
Tag::ORIGIN
, który używa wartości identyfikatora 702. -
rollbackResistant
-
Dostępne tylko w wersjach atestacji klucza 1 i 2.
Odpowiada tagowi autoryzacji
Tag::ROLLBACK_RESISTANT
, który używa wartości identyfikatora tagu 703. -
rootOfTrust
-
Odpowiada tagowi autoryzacji
Tag::ROOT_OF_TRUST
, który używa wartości identyfikatora tagu 704.Więcej informacji znajdziesz w sekcji opisującej strukturę danych RootOfTrust.
-
osVersion
-
Odpowiada tagowi autoryzacji
Tag::OS_VERSION
, który używa wartości identyfikatora tagu 705.Wersja systemu operacyjnego Android powiązana z kluczem Keymasterem, podana jako 6-cyfrowa liczba całkowita. Na przykład wersja 8.1.0 jest reprezentowana jako 080100.
Tę wartość na liście autoryzacji uwzględnia tylko Keymaster w wersji 1.0 lub nowszej.
-
osPatchLevel
-
Odpowiada tagowi autoryzacji
Tag::PATCHLEVEL
, który korzysta z wartości identyfikatora tagu 706.Miesiąc i rok powiązane z używanym w Keymasterze poprawką bezpieczeństwa, podany jako sześciocyfrowa liczba całkowita. Na przykład poprawka z sierpnia 2018 r. ma postać 201808.
Tę wartość na liście autoryzacji uwzględnia tylko Keymaster w wersji 1.0 lub nowszej.
-
attestationApplicationId
-
Występuje tylko w wersjach klucza z weryfikacją ≥2.
Odpowiada to tagowi autoryzacji Keymaster
Tag::ATTESTATION_APPLICATION_ID
, który korzysta z wartości identyfikatora tagu 709.Więcej informacji znajdziesz w sekcji opisującej strukturę danych AttestationApplicationId.
-
attestationIdBrand
-
Występuje tylko w wersjach klucza z weryfikacją ≥2.
Odpowiada tagowi Keymaster (
Tag::ATTESTATION_ID_BRAND
), który używa wartości identyfikatora 710. -
attestationIdDevice
-
Występuje tylko w wersjach klucza z weryfikacją ≥2.
Odpowiada tagowi Keymaster (
Tag::ATTESTATION_ID_DEVICE
), który używa wartości identyfikatora 711. -
attestationIdProduct
-
Występuje tylko w wersjach klucza z weryfikacją ≥2.
Odpowiada tagowi Keymaster (
Tag::ATTESTATION_ID_PRODUCT
), który używa wartości identyfikatora 712. -
attestationIdSerial
-
Występuje tylko w wersjach klucza z weryfikacją ≥2.
Odpowiada tagowi Keymaster
Tag::ATTESTATION_ID_SERIAL
, który ma identyfikator tagu o wartości 713. -
attestationIdImei
-
Występuje tylko w wersjach klucza z weryfikacją ≥2.
Odpowiada tagowi autoryzacji
Tag::ATTESTATION_ID_IMEI
, który używa wartości identyfikatora tagu 714. -
attestationIdMeid
-
Jest widoczny tylko w wersjach atestu klucza >= 2.
Odpowiada tagowi autoryzacji
Tag::ATTESTATION_ID_MEID
, który używa wartości identyfikatora tagu 715. -
attestationIdManufacturer
-
Występuje tylko w wersjach klucza z weryfikacją ≥2.
Odpowiada tagowi autoryzacji
Tag::ATTESTATION_ID_MANUFACTURER
, który używa wartości identyfikatora tagu 716. -
attestationIdModel
-
Występuje tylko w wersjach klucza z weryfikacją ≥2.
Odpowiada tagowi autoryzacji
Tag::ATTESTATION_ID_MODEL
, który używa wartości identyfikatora tagu 717. -
vendorPatchLevel
-
Dostępne tylko w wersjach weryfikacji klucza >= 3.
Odpowiada tagowi autoryzacji
Tag::VENDOR_PATCHLEVEL
, który używa wartości identyfikatora tagu 718.Określa poziom zabezpieczeń obrazu dostawcy, który musi być zainstalowany na urządzeniu, aby można było używać tego klucza. Wartość jest wyświetlana w formacie RRRRMMDD, co oznacza datę poprawki zabezpieczeń od dostawcy. Jeśli na przykład klucz został wygenerowany na urządzeniu z Androidem, na którym zainstalowano poprawkę zabezpieczeń z 1 sierpnia 2018 r., wartość ta wynosi 20180801.
-
bootPatchLevel
-
Jest dostępny tylko w wersjach atestu klucza >= 3.
Odpowiada tagowi autoryzacji
Tag::BOOT_PATCHLEVEL
, który używa wartości identyfikatora tagu 719.Określa poziom poprawki zabezpieczeń obrazu jądra, która musi być zainstalowana na urządzeniu, aby można było używać tego klucza. Wartość ma postać RRRRMMDD, co oznacza datę poprawki zabezpieczeń systemu. Jeśli na przykład klucz został wygenerowany na urządzeniu z Androidem z zainstalowaną poprawką bezpieczeństwa z 5 sierpnia 2018 r., jego wartość będzie wynosić 20180805.
-
deviceUniqueAttestation
-
Dostępne tylko w wersjach weryfikacji klucza >= 4.
Odpowiada tagowi autoryzacji
Tag::DEVICE_UNIQUE_ATTESTATION
, który ma wartość identyfikatora tagu 720. -
attestationIdSecondImei
-
Występuje tylko w wersjach klucza z atestatem większym niż 300.
Odpowiada tagowi autoryzacji
Tag::ATTESTATION_ID_SECOND_IMEI
, który używa wartości identyfikatora tagu 723.
Pola RootOfTrust
-
verifiedBootKey
- Bezpieczny skrót klucza publicznego służący do weryfikacji integralności i autentyczności całego kodu, który jest wykonywany podczas uruchamiania urządzenia w ramach zaufanej kontroli startowej. Zalecamy użycie SHA-256.
-
deviceLocked
- Czy program rozruchowy urządzenia jest zablokowany.
true
oznacza, że urządzenie uruchomiło podpisany obraz, który został zweryfikowany przez weryfikację podczas uruchamiania. -
verifiedBootState
- Stan weryfikacji podczas uruchamiania urządzenia.
-
verifiedBootHash
- Skrót wszystkich danych chronionych przez funkcję weryfikacji podczas uruchamiania. W przypadku urządzeń korzystających z implementacji referencyjnej Android Verified Boot to pole zawiera skrót VBMeta.
Wartości VerifiedBootState
Wartość | Odpowiadający stan uruchamiania | Znaczenie |
---|---|---|
Verified |
GREEN |
Pełny łańcuch zaufania rozciąga się od chronionego sprzętowo korzenia zaufania do programu rozruchowego i wszystkich partycji zweryfikowanych przez zaufany rozruch.
W tym stanie pole verifiedBootKey zawiera haszzaimplementowanego głównego zaufanego elementu, czyli certyfikatu wbudowanego w ROM przez producenta urządzenia fabrycznie. |
SelfSigned |
YELLOW |
To samo co Verified , z tym że weryfikacja została przeprowadzona
za pomocą
zaufania skojarzonego z rootem zaufania skonfigurowanym przez użytkownika
zamiast za pomocą
zaawansowanego zaufania skojarzonego z rootem zaufania skonfigurowanym przez producenta.
W tym stanie pole verifiedBootKey zawiera hasz klucza publicznego skonfigurowanego przez użytkownika. |
Unverified |
ORANGE |
Program rozruchowy urządzenia jest odblokowany, dlatego nie można ustanowić łańcucha zaufania. Urządzenie może być dowolnie modyfikowane, dlatego integralność urządzenia musi być weryfikowana przez użytkownika poza pasmem. W tym stanie pole verifiedBootKey zawiera 32 bajty z zerami. |
Failed |
RED |
Urządzenie nie przeszło weryfikacji. W obecnej chwili nie można zagwarantować, że zawartość pozostałych pól RootOfTrust jest poprawna. |
Identyfikator aplikacji atestu
To pole odzwierciedla przekonanie platformy Androida co do tego, które aplikacje mogą używać materiału tajnego klucza w ramach atestu. Może zawierać wiele pakietów, o ile mają one ten sam identyfikator UID. Pole AttestationApplicationId
w AuthorizationList
jest typu OCTET_STRING
i ma format zgodny z tym schematem ASN.1:
AttestationApplicationId ::= SEQUENCE { package_infos SET OF AttestationPackageInfo, signature_digests SET OF OCTET_STRING, } AttestationPackageInfo ::= SEQUENCE { package_name OCTET_STRING, version INTEGER, }
package_infos
-
Zbiór obiektów
AttestationPackageInfo
, z których każdy zawiera nazwę i numer wersji pakietu. signature_digests
-
Zestaw skrótów SHA-256 certyfikatów podpisywania aplikacji. Aplikacja może mieć wiele łańcuchów certyfikatów klucza podpisywania. W przypadku każdego z nich certyfikat „liścia” jest przetwarzany i umieszczany w polu
signature_digests
. Nazwa pola wprowadza w błąd, ponieważ zebrane dane to certyfikaty podpisywania aplikacji, a nie podpisy aplikacji, bo nazwa pochodzi od klasySignature
zwróconej przez wywołaniegetPackageInfo()
. Ten fragment kodu pokazuje przykładowy zestaw:{SHA256(PackageInfo.signature[0]), SHA256(PackageInfo.signature[1]), ...}
Unikalny identyfikator
Unikalny identyfikator to 128-bitowa wartość, która identyfikuje urządzenie, ale tylko przez ograniczony czas. Wartość jest obliczana na podstawie:
HMAC_SHA256(T || C || R, HBK)
Gdzie:
T
to „tymczasowa wartość licznika” obliczona przez podzielenie wartościTag::CREATION_DATETIME
przez 2592000000, usuwając resztę.T
zmienia się co 30 dni (2592000000 = 30 * 24 * 60 * 60 * 1000).C
to wartośćTag::APPLICATION_ID
R
to 1, jeśli w parametry attest_params wywołania attest_key podany jest parametrTag::RESET_SINCE_ID_ROTATION
, lub 0, jeśli go nie ma.HBK
to unikalny, powiązany ze sprzętem sekret znany zaufanemu środowisku wykonawczemu, który nigdy nie jest przez nie ujawniany. Obiekt tajny zawiera co najmniej 128 bitów entropii i jest unikalny dla danego urządzenia (przy 128 bitach entropii dopuszczalna jest unikalność probabilistyczna). HBK powinien być uzyskany ze scalonego materiału klucza za pomocą HMAC lub AES_CMAC.
Skróć dane wyjściowe HMAC_SHA256 do 128 bitów.
Klucze atestu i certyfikaty
Na urządzeniu są bezpiecznie udostępniane 2 klucze (jeden RSA i jeden ECDSA) oraz odpowiadające im łańcuchy certyfikatów.
Android 12 wprowadza zdalne udostępnianie kluczy, a Android 13 wymaga jego implementacji na urządzeniach. Zdalne udostępnianie kluczy zapewnia urządzeniom w polu certyfikaty weryfikacyjne ECDSA P256 dla każdej aplikacji. Ich ważność jest krótsza niż w przypadku certyfikatów udostępnionych fabrycznie.
Wiele numerów IMEI
Android 14 obsługuje wiele numerów IMEI w rekordzie atestu klucza w Androidzie. OEM może wdrożyć tę funkcję, dodając tag KeyMint dla drugiego numeru IMEI. Coraz częściej urządzenia mają wiele radia komórkowego, a producenci OEM mogą teraz obsługiwać urządzenia z 2 numerami IMEI.
Producenci OEM muszą mieć drugi numer IMEI, jeśli jest obecny na ich urządzeniach, aby udostępnić go implementacjom KeyMint, aby te implementacje mogły go potwierdzić w taki sam sposób jak pierwszy numer IMEI.
Potwierdzenie tożsamości
Android 8.0 zawiera opcjonalną obsługę uwierzytelniania tożsamości na urządzeniach z Keymaster 3. Potwierdzenie tożsamości umożliwia urządzeniu przedstawienie dowodu tożsamości sprzętowej, takiego jak numer seryjny lub IMEI. Chociaż jest to funkcja opcjonalna, zalecamy, aby wszystkie implementacje Keymaster 3 ją obsługiwały, ponieważ możliwość potwierdzenia tożsamości urządzenia umożliwia stosowanie takich rozwiązań jak prawdziwa konfiguracja zdalna bezdotykowa z większym bezpieczeństwem (ponieważ strona zdalna może mieć pewność, że komunikuje się z odpowiednim urządzeniem, a nie z urządzeniem podszywającym się pod to urządzenie).
Poświadczenie tożsamości działa poprzez tworzenie kopii identyfikatorów sprzętowych urządzenia, do których dostęp ma tylko Trusted Execution Environment (TEE) przed opuszczeniem fabryki. Użytkownik może odblokować bootloader urządzenia i zmienić oprogramowanie systemowe oraz identyfikatory zgłaszane przez frameworki Androida. Kopie identyfikatorów przechowywanych przez TEE nie mogą być w ten sposób modyfikowane, co gwarantuje, że poświadczenie tożsamości identyfikatora urządzenia odnosi się tylko do oryginalnych identyfikatorów sprzętowych urządzenia, uniemożliwiając w ten sposób próby podszywania się pod inne urządzenia.
Główna interfejs API do weryfikacji tożsamości opiera się na istniejącym mechanizmie weryfikacji klucza wprowadzonym w Keymaster 2. Gdy żądanie certyfikatu atestatycznego dla klucza przechowywanego przez właściciela klucza, dzwoniący może poprosić o uwzględnienie identyfikatorów sprzętowych urządzenia w metadanych certyfikatu atestatycznego. Jeśli klucz jest przechowywany w TEE, certyfikat jest powiązany z znanym głównym urzędem zaufania. Odbiorca takiego certyfikatu może zweryfikować, czy certyfikat i jego zawartość, w tym identyfikatory sprzętowe, zostały zapisane przez TEE. Gdy poprosisz o uwzględnienie identyfikatorów sprzętowych w certyfikacie, TEE potwierdza tylko te identyfikatory, które są przechowywane w magazynie, zgodnie z danymi wypełnionymi na hali produkcyjnej.
Właściwości miejsca na dane
Pamięć urządzenia z identyfikatorami urządzeń musi mieć te właściwości:
- Wartości pochodzące z pierwotnych identyfikatorów urządzenia są kopiowane do pamięci przed wyprodukowaniem urządzenia.
- Metoda
destroyAttestationIds()
może trwale usunąć tę kopię danych pochodzących z identyfikatora. Oznacza to, że dane zostaną całkowicie usunięte, więc nie będzie można ich przywrócić ani przywracając urządzenie do ustawień fabrycznych, ani wykonując inną procedurę. Jest to szczególnie ważne w przypadku urządzeń, na których użytkownik odblokował bootloader, zmienił oprogramowanie systemowe i zmodyfikował identyfikatory zwracane przez frameworki Androida. - Obiekty RMA powinny mieć możliwość generowania nowych kopii danych pochodzących z identyfikatora sprzętu. Dzięki temu urządzenie, które przejdzie proces RMA, może ponownie przeprowadzić atest identyfikatora. Mechanizm używany przez usługi RMA musi być chroniony, aby użytkownicy nie mogli go sami wywoływać, ponieważ pozwoliłoby im to uzyskać potwierdzenia sfałszowanych identyfikatorów.
- Żaden kod poza zaufaną aplikacją Keymaster w TEE nie jest w stanie odczytać danych pochodzących z identyfikatorów przechowywanych w pamięci.
- Pamięć jest zabezpieczona przed nieuprawnionym dostępem: jeśli zawartość pamięci została zmodyfikowana, TEE traktuje to tak, jakby kopie treści zostały zniszczone, i odrzuca wszystkie próby uwierzytelniania tożsamości. Można to zrobić, podpisując lub oznaczając MAC-iem miejsce na dane w sposób opisany poniżej.
- W pamięci nie są przechowywane pierwotne identyfikatory. Ponieważ weryfikacja tożsamości wymaga odpowiedzi na wyzwanie, dzwoniący zawsze podaje identyfikatory, które mają zostać zweryfikowane. TEE musi tylko sprawdzić, czy te wartości są zgodne z wartościami pierwotnymi. Aby umożliwić tę weryfikację, przechowuj szyfrowane hasze pierwotnych wartości zamiast wartości.
Budownictwo
Aby utworzyć implementację z wymienionymi wyżej właściwościami, przechowuj wartości pochodzące z identyfikatora za pomocą tej konstrukcji S. Nie przechowuj innych kopii wartości identyfikatorów z wyjątkiem normalnych miejsc w systemie, które właściciel urządzenia może zmodyfikować przez dostęp do roota:
S = D || HMAC(HBK, D)
gdzie:
D = HMAC(HBK, ID1) || HMAC(HBK, ID2) || ... || HMAC(HBK, IDn)
HMAC
to konstrukcja HMAC z odpowiednim bezpiecznym haszem (zalecamy SHA-256)HBK
to klucz powiązany z sprzętem, który nie jest używany do innych celówID1...IDn
to pierwotne wartości identyfikatorów. Powiązanie konkretnej wartości z konkretnym indeksem zależy od implementacji, ponieważ poszczególne urządzenia mają różne numery identyfikatorów.||
oznacza koniunkcję
Dane wyjściowe HMAC mają stały rozmiar, więc do znalezienia poszczególnych haszów identyfikatorów ani HMAC D nie są wymagane żadne nagłówki ani inne struktury. Oprócz sprawdzania podanych wartości w celu wykonania uwierzytelnienia implementacje muszą również zweryfikować S, wyodrębniając z niego D, obliczając HMAC(HBK, D) i porównując go z wartością w S, aby sprawdzić, czy żadne indywidualne identyfikatory nie zostały zmodyfikowane lub uszkodzone. Implementacje muszą też korzystać z porównań w stałym czasie wszystkich poszczególnych elementów identyfikatora oraz weryfikacji S. Czas porównania musi być stały niezależnie od liczby podanych identyfikatorów i prawidłowego dopasowania dowolnej części testu.
Identyfikatory sprzętowe
Uwierzytelnianie tożsamości obsługuje te identyfikatory sprzętowe:
- Nazwa marki zwracana przez
Build.BRAND
w Androidzie - Nazwa urządzenia zwracana przez
Build.DEVICE
w Androidzie - Nazwa produktu zwracana przez
Build.PRODUCT
w Androidzie - Nazwa producenta wyświetlana przez aplikację
Build.MANUFACTURER
na Androidzie - Nazwa modelu zwracana przez funkcję
Build.MODEL
w Androidzie - Numer seryjny
- Numery IMEI wszystkich urządzeń radiowych
- Identyfikatory MEID wszystkich radia
Aby zapewnić obsługę poświadczania identyfikatorów urządzeń, urządzenie je potwierdza te identyfikatory. Wszystkie urządzenia z Androidem mają te 6 funkcji, które są niezbędne do działania tej funkcji. Jeśli urządzenie ma wbudowane radio komórkowe, musi również obsługiwać uwierzytelnianie numerów IMEI lub MEID radia.
Uwierzytelnianie tożsamości jest wymagane w ramach weryfikacji klucza i uwzględnienia w żądaniu identyfikatorów urządzeń. Identyfikatory są oznaczone jako:
ATTESTATION_ID_BRAND
ATTESTATION_ID_DEVICE
ATTESTATION_ID_PRODUCT
ATTESTATION_ID_MANUFACTURER
ATTESTATION_ID_MODEL
ATTESTATION_ID_SERIAL
ATTESTATION_ID_IMEI
ATTESTATION_ID_MEID
Identyfikator do potwierdzenia to ciąg bajtów zakodowany w UTF-8. Ten format dotyczy również identyfikatorów liczbowych. Każdy identyfikator do potwierdzenia jest wyrażony jako ciąg znaków zakodowany w formacie UTF-8.
Jeśli urządzenie nie obsługuje weryfikacji tożsamości (lub destroyAttestationIds()
zostało wcześniej wywołane i urządzenie nie może już weryfikować swoich identyfikatorów), każde żądanie weryfikacji klucza, które zawiera co najmniej jeden z tych tagów, kończy się niepowodzeniem z wartością ErrorCode::CANNOT_ATTEST_IDS
.
Jeśli urządzenie obsługuje uwierzytelnianie tożsamości, a w prośbie o uwierzytelnienie klucza uwzględniono co najmniej jeden z wymienionych powyżej tagów, TEE sprawdza, czy identyfikator podany w każdym z tych tagów jest zgodny z kopią identyfikatorów sprzętowych. Jeśli co najmniej 1 identyfikator nie pasuje, cała weryfikacja zakończy się niepowodzeniem z komunikatem ErrorCode::CANNOT_ATTEST_IDS
. Prawidłowy, gdy ten sam tag
podaje wiele razy. Może to być przydatne na przykład podczas weryfikowania numerów IMEI:
Urządzenie może mieć kilka modułów radiowych z różnymi numerami IMEI. Prośba o potwierdzenie jest ważna, jeśli wartość podana w każdym ATTESTATION_ID_IMEI
jest zgodna z jednym z interfejsów radiowych urządzenia. To samo dotyczy wszystkich pozostałych tagów.
Jeśli weryfikacja zakończy się powodzeniem, uwierzytelnione identyfikatory zostaną dodane do rozszerzenia atesta (OID 1.3.6.1.4.1.11129.2.1.17) wydanego certyfikatu atesta, korzystając ze schematu podanego powyżej. Zmiany w schemacie atestu Keymaster 2 są pogrubione razem z komentarzami.
Java API
Ta sekcja ma tylko charakter informacyjny. Implementatorzy Keymaster nie implementują ani nie używają interfejsu Java API. Informacje te mają pomóc implementatorom zrozumieć, jak aplikacje korzystają z tej funkcji. Składniki systemu mogą używać tego parametru w inny sposób, dlatego ważne jest, aby ta sekcja nie była traktowana jako normatywna.