Keystore มอบพื้นที่ที่ปลอดภัยยิ่งขึ้นในการสร้าง จัดเก็บ และใช้คีย์เข้ารหัสในลักษณะที่มีการควบคุม เมื่อมีและใช้ที่เก็บข้อมูลคีย์ที่สนับสนุนด้วยฮาร์ดแวร์ วัสดุคีย์จะมีความปลอดภัยมากขึ้นจากการดึงข้อมูลจากอุปกรณ์ และ Keymaster จะบังคับใช้ข้อจำกัดที่ยากต่อการล้มล้าง
นี่เป็นเรื่องจริงเท่านั้น อย่างไรก็ตาม หากทราบว่าคีย์ที่เก็บคีย์อยู่ในหน่วยเก็บข้อมูลที่สนับสนุนฮาร์ดแวร์ ใน Keymaster 1 ไม่มีวิธีใดที่แอปหรือเซิร์ฟเวอร์ระยะไกลจะตรวจสอบได้อย่างน่าเชื่อถือว่าเป็นกรณีนี้หรือไม่ ดีมอนที่เก็บคีย์โหลดคีย์มาสเตอร์ HAL ที่มีอยู่และเชื่อทุกสิ่งที่ HAL พูดเกี่ยวกับการสำรองฮาร์ดแวร์ของคีย์
เพื่อแก้ไขปัญหานี้ Keymaster ได้แนะนำการรับรองคีย์ ใน Android 7.0 (Keymaster 2) และการรับรอง ID ใน Android 8.0 (Keymaster 3)
การรับรองคีย์มีจุดมุ่งหมายเพื่อให้มีวิธีในการพิจารณาว่าคู่คีย์แบบอสมมาตรได้รับการสนับสนุนด้วยฮาร์ดแวร์หรือไม่ คุณสมบัติของคีย์คืออะไร และข้อจำกัดใดบ้างที่นำไปใช้กับการใช้งาน
การรับรองรหัสช่วยให้อุปกรณ์แสดงหลักฐานตัวระบุฮาร์ดแวร์ เช่น หมายเลขซีเรียลหรือ IMEI
การรับรองที่สำคัญ
เพื่อรองรับการรับรองคีย์ Android 7.1 ได้แนะนำชุดแท็ก ประเภท และวิธีการให้กับ HAL
แท็ก
-
Tag::ATTESTATION_CHALLENGE
-
Tag::INCLUDE_UNIQUE_ID
-
Tag::RESET_SINCE_ID_ROTATION
พิมพ์
คีย์มาสเตอร์ 2 และต่ำกว่า
typedef struct { keymaster_blob_t* entries; size_t entry_count; } keymaster_cert_chain_t;
วิธีการ AttestKey
คีย์มาสเตอร์ 3
attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams) generates(ErrorCode error, vec<vec<uint8_t>> certChain);
คีย์มาสเตอร์ 2 และต่ำกว่า
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
คือโครงสร้างอุปกรณ์คีย์มาสเตอร์ -
keyToAttest
คือคีย์ Blob ที่ส่งคืนจากgenerateKey
ซึ่งจะสร้างการรับรอง -
attestParams
คือรายการพารามิเตอร์ที่จำเป็นสำหรับการรับรอง ซึ่งรวมถึงTag::ATTESTATION_CHALLENGE
และอาจเป็นTag::RESET_SINCE_ID_ROTATION
ตลอดจนTag::APPLICATION_ID
และTag::APPLICATION_DATA
สองอันหลังจำเป็นในการถอดรหัสคีย์หยดหากระบุไว้ในระหว่างการสร้างคีย์ -
certChain
เป็นพารามิเตอร์เอาต์พุต ซึ่งส่งคืนอาร์เรย์ของใบรับรอง รายการ 0 คือใบรับรองการรับรอง ซึ่งหมายความว่าจะรับรองคีย์จากkeyToAttest
และมีส่วนขยายการรับรอง
เมธอด attestKey
ถือเป็นการดำเนินการกับคีย์สาธารณะบนคีย์ที่รับรอง เนื่องจากสามารถเรียกได้ตลอดเวลาและไม่จำเป็นต้องเป็นไปตามข้อจำกัดในการให้สิทธิ์ ตัวอย่างเช่น หากคีย์ที่ได้รับการรับรองต้องมีการตรวจสอบสิทธิ์ผู้ใช้จึงจะใช้งานได้ สามารถสร้างการยืนยันได้โดยไม่ต้องมีการตรวจสอบสิทธิ์ผู้ใช้
ใบรับรองการรับรอง
ใบรับรองการรับรองคือใบรับรอง X.509 มาตรฐาน โดยมีส่วนขยายการรับรองเพิ่มเติมซึ่งมีคำอธิบายของคีย์ที่รับรอง ใบรับรองมีการลงนามด้วย คีย์รับรอง ที่ได้รับการรับรอง คีย์การรับรองอาจใช้อัลกอริทึมที่แตกต่างจากคีย์ที่กำลังรับรอง
ใบรับรองการรับรองมีช่องในตารางด้านล่างและไม่สามารถมีช่องเพิ่มเติมได้ บางฟิลด์ระบุค่าฟิลด์คงที่ การทดสอบ CTS จะตรวจสอบว่าเนื้อหาใบรับรองตรงตามที่กำหนดไว้ทุกประการ
ลำดับใบรับรอง
ชื่อฟิลด์ (ดู RFC 5280 ) | ค่า |
---|---|
tbsใบรับรอง | ลำดับใบรับรอง TBSC |
อัลกอริธึมลายเซ็น | AlgorithmIdentifier ของอัลกอริทึมที่ใช้ในการลงนามคีย์: ECDSA สำหรับคีย์ EC, RSA สำหรับคีย์ RSA |
ค่าลายเซ็น | BIT STRING ลายเซ็นคำนวณบนใบรับรอง tbsCertificate ที่เข้ารหัส ASN.1 DER |
ลำดับใบรับรอง TBSC
ชื่อฟิลด์ (ดู RFC 5280 ) | ค่า |
---|---|
version | จำนวนเต็ม 2 (หมายถึงใบรับรอง v3) |
serialNumber | INTEGER 1 (ค่าคงที่: เหมือนกันใน ทุก ใบรับรอง) |
signature | AlgorithmIdentifier ของอัลกอริทึมที่ใช้ในการลงนามคีย์: ECDSA สำหรับคีย์ EC, RSA สำหรับคีย์ RSA |
issuer | เหมือนกับช่องเรื่องของคีย์การรับรองแบบแบตช์ |
validity | SEQUENCE ของสองวันที่ ซึ่งมีค่าของ Tag::ACTIVE_DATETIME และ Tag::USAGE_EXPIRE_DATETIME ค่าเหล่านั้นอยู่ในหน่วยมิลลิวินาทีตั้งแต่วันที่ 1 มกราคม 1970 ดู RFC 5280 สำหรับการแสดงวันที่ที่ถูกต้องในใบรับรอง หากไม่มี Tag::ACTIVE_DATETIME ให้ใช้ค่าของ Tag::CREATION_DATETIME หากไม่มี Tag::USAGE_EXPIRE_DATETIME ให้ใช้วันหมดอายุของใบรับรองคีย์การรับรองแบบแบตช์ |
subject | CN = "รหัส Android Keystore" (ค่าคงที่: เหมือนกันใน ทุก ใบรับรอง) |
subjectPublicKeyInfo | SubjectPublicKeyInfo มีกุญแจสาธารณะที่ได้รับการรับรอง |
extensions/Key Usage | digitalSignature: ตั้งค่าว่าคีย์มีวัตถุประสงค์ KeyPurpose::SIGN หรือ KeyPurpose::VERIFY บิตอื่นๆ ทั้งหมดไม่ได้ตั้งค่า |
extensions/CRL Distribution Points | มูลค่าจะแจ้งภายหลัง |
extensions/"attestation" | OID คือ 1.3.6.1.4.1.11129.2.1.17; เนื้อหาถูกกำหนดไว้ในส่วนส่วนขยายการรับรองด้านล่าง เช่นเดียวกับส่วนขยายใบรับรอง X.509 ทั้งหมด เนื้อหาจะแสดงเป็น OCTET_STRING ซึ่งมีการเข้ารหัส DER ของ SEQUENCE การรับรอง |
การขยายเวลารับรอง
ส่วนขยาย attestation
ประกอบด้วยคำอธิบายที่สมบูรณ์ของการอนุญาตคีย์มาสเตอร์ที่เกี่ยวข้องกับคีย์ ในโครงสร้างที่สอดคล้องโดยตรงกับรายการการอนุญาตที่ใช้ใน Android และคีย์มาสเตอร์ HAL แต่ละแท็กในรายการการอนุญาตจะแสดงด้วยรายการ ASN.1 SEQUENCE
ซึ่งแท็กไว้อย่างชัดเจนด้วยหมายเลขแท็กคีย์มาสเตอร์ แต่มีการปกปิดประเภท (บิตลำดับสูงสี่บิต)
ตัวอย่างเช่น ใน Keymaster 3 Tag::PURPOSE
ถูกกำหนดใน types.hal เป็น ENUM_REP | 1
. สำหรับส่วนขยายการรับรอง ค่า ENUM_REP
จะถูกลบออก โดยเหลือแท็ก 1
(สำหรับ Keymaster 2 และต่ำกว่า KM_TAG_PURPOSE
ถูกกำหนดไว้ใน keymaster_defs.h.)
ค่าต่างๆ ได้รับการแปลอย่างตรงไปตรงมาเป็นประเภท ASN.1 ตามตารางนี้:
ประเภทคีย์มาสเตอร์ | ประเภท ASN.1 |
---|---|
ENUM | จำนวนเต็ม |
ENUM_REP | SET ของจำนวนเต็ม |
UINT | จำนวนเต็ม |
UINT_REP | SET ของจำนวนเต็ม |
ULONG | จำนวนเต็ม |
ULONG_REP | SET ของจำนวนเต็ม |
DATE | INTEGER (มิลลิวินาทีตั้งแต่ 1 มกราคม 1970 00:00:00 GMT) |
BOOL | NULL (ในคีย์มาสเตอร์ แท็กปัจจุบันหมายถึงจริง ขาดหายไปหมายถึงเท็จ ความหมายเดียวกันนี้ใช้กับการเข้ารหัส ASN.1) |
BIGNUM | ไม่ได้ใช้ในปัจจุบัน ดังนั้นจึงไม่มีการกำหนดแผนที่ |
BYTES | OCTET_STRING |
สคีมา
เนื้อหาส่วนขยายการรับรองอธิบายโดยสคีมา ASN.1 ต่อไปนี้
KeyDescription ::= SEQUENCE { attestationVersion INTEGER, # KM2 value is 1. KM3 value is 2. KM4 value is 3. attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, teeEnforced 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, # KM4 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, # KM4 trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, # KM4 unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, # KM4 allApplications [600] EXPLICIT NULL OPTIONAL, applicationId [601] EXPLICIT OCTET_STRING OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rollbackResistant [703] EXPLICIT NULL OPTIONAL, # KM2 and KM3 only. rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, # KM3 vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, # KM4 bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, # KM4 } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, # KM4 } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
ฟิลด์คำอธิบายคีย์
ฟิลด์ keymasterVersion
และ attestationChallenge
จะถูกระบุตำแหน่ง แทนที่จะเป็นแท็ก ดังนั้นแท็กในรูปแบบที่เข้ารหัสจะระบุเฉพาะประเภทฟิลด์เท่านั้น ฟิลด์ที่เหลือจะถูกแท็กโดยปริยายตามที่ระบุไว้ในสคีมา
ชื่อฟิลด์ | พิมพ์ | ค่า |
---|---|---|
attestationVersion | จำนวนเต็ม | เวอร์ชันของสคีมาการรับรอง: 1, 2 หรือ 3 |
attestationSecurity | ระดับความปลอดภัย | ระดับความปลอดภัยของการรับรองนี้ คุณสามารถรับการรับรองซอฟต์แวร์ของคีย์ที่สนับสนุนฮาร์ดแวร์ได้ การรับรองดังกล่าวไม่สามารถเชื่อถือได้หากระบบ Android ถูกบุกรุก |
keymasterVersion | จำนวนเต็ม | เวอร์ชันของอุปกรณ์คีย์มาสเตอร์: 0, 1, 2, 3 หรือ 4 |
keymasterSecurity | ระดับความปลอดภัย | ระดับความปลอดภัยของการใช้งานคีย์มาสเตอร์ |
attestationChallenge | OCTET_STRING | ค่าของ Tag::ATTESTATION_CHALLENGE ระบุในคำขอรับรอง |
uniqueId | OCTET_STRING | รหัสที่ไม่ซ้ำซึ่งเป็นทางเลือก แสดงหากคีย์มี Tag::INCLUDE_UNIQUE_ID |
softwareEnforced | รายการอนุญาต | การอนุญาตคีย์มาสเตอร์ทางเลือกที่ไม่ได้บังคับใช้โดย TEE ถ้ามี |
teeEnforced | รายการอนุญาต | ทางเลือก การอนุญาต Keymaster ที่บังคับใช้โดย TEE ถ้ามี |
เขตข้อมูลรายการอนุญาต
ฟิลด์ AuthorizationList
เป็นทางเลือกทั้งหมดและระบุด้วยค่าแท็กคีย์มาสเตอร์ โดยมีบิตประเภทถูกพรางไว้ การติดแท็กที่ชัดเจนถูกใช้เพื่อให้ฟิลด์ต่างๆ มีแท็กที่ระบุประเภท ASN.1 เพื่อให้แยกวิเคราะห์ได้ง่ายขึ้น
สำหรับรายละเอียดเกี่ยวกับค่าของแต่ละฟิลด์ โปรดดูที่ types.hal
สำหรับ Keymaster 3 และ keymaster_defs.h
สำหรับ Keymaster 2 และด้านล่าง ชื่อแท็กคีย์มาสเตอร์ถูกแปลงเป็นชื่อฟิลด์โดยละเว้นคำนำหน้า KM_TAG
และเปลี่ยนส่วนที่เหลือเป็นตัวพิมพ์แบบคาเมล ดังนั้น Tag::KEY_SIZE
จึงกลายเป็น keySize
ฟิลด์ RootOfTrust
ฟิลด์ RootOfTrust
ถูกระบุตำแหน่ง
ชื่อฟิลด์ | พิมพ์ | ค่า |
---|---|---|
verifiedBootKey | OCTET_STRING | แฮชที่ปลอดภัยของคีย์ที่ใช้ในการตรวจสอบอิมเมจระบบ แนะนำให้ใช้ SHA-256 |
deviceLocked | บูลีน | เป็นจริงหากบูตโหลดเดอร์ถูกล็อค ซึ่งหมายความว่าสามารถแฟลชได้เฉพาะอิมเมจที่เซ็นชื่อเท่านั้น และการตรวจสอบการบูตที่ได้รับการยืนยันก็เสร็จสิ้น |
verifiedBootState | ตรวจสอบ BootState แล้ว | สถานะของการบูตที่ตรวจสอบแล้ว |
verifiedBootHash | OCTET_STRING | สรุปข้อมูลทั้งหมดที่ได้รับการคุ้มครองโดย Verified Boot สำหรับอุปกรณ์ที่ใช้ Android Verified Boot ของ Verified Boot ค่านี้ประกอบด้วยไดเจสต์ของ โครงสร้าง VBMeta หรือโครงสร้างข้อมูลเมตาของ Verified Boot หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับวิธีการคำนวณค่านี้ โปรดดูที่ VBMeta Digest |
ค่า VerifiedBootState
ค่าของ verifiedBootState
มีความหมายดังต่อไปนี้:
ค่า | ความหมาย |
---|---|
Verified | บ่งชี้ถึงความน่าเชื่อถือแบบครบวงจรที่ขยายจากบูตโหลดเดอร์ไปยังพาร์ติชันที่ได้รับการตรวจสอบ รวมถึงบูตโหลดเดอร์ พาร์ติชันสำหรับบูต และพาร์ติชันที่ได้รับการตรวจสอบทั้งหมด ในสถานะนี้ ค่า verifiedBootKey คือแฮชของใบรับรองแบบฝัง ซึ่งหมายความว่าใบรับรองที่ไม่สามารถเปลี่ยนแปลงได้ถูกเบิร์นลงใน ROMสถานะนี้สอดคล้องกับสถานะการบูต สีเขียว ตามที่ระบุไว้ในเอกสาร ประกอบขั้นตอนการบูตที่ตรวจสอบแล้ว |
SelfSigned | บ่งชี้ว่าพาร์ติชันสำหรับเริ่มระบบได้รับการตรวจสอบโดยใช้ใบรับรองแบบฝัง และลายเซ็นนั้นถูกต้อง โปรแกรมโหลดบูตจะแสดงคำเตือนและลายนิ้วมือของคีย์สาธารณะก่อนที่จะอนุญาตให้กระบวนการบูตดำเนินการต่อ ในสถานะนี้ ค่า verifiedBootKey คือแฮชของใบรับรองที่ลงนามด้วยตนเองสถานะนี้สอดคล้องกับสถานะการบูต สีเหลือง ตามที่ระบุไว้ในเอกสาร ประกอบขั้นตอนการบูตที่ตรวจสอบแล้ว |
Unverified | บ่งชี้ว่าอุปกรณ์อาจได้รับการแก้ไขอย่างอิสระ ความสมบูรณ์ของอุปกรณ์เป็นหน้าที่ของผู้ใช้เพื่อตรวจสอบนอกแบนด์ Bootloader จะแสดงคำเตือนแก่ผู้ใช้ก่อนที่จะอนุญาตให้กระบวนการบู๊ตดำเนินต่อไป ในสถานะนี้ ค่า verifiedBootKey ว่างเปล่าสถานะนี้สอดคล้องกับสถานะการบูต สีส้ม ตามที่ระบุไว้ในเอกสาร ประกอบขั้นตอนการบูตที่ตรวจสอบแล้ว |
Failed | แสดงว่าอุปกรณ์ไม่ผ่านการตรวจสอบ จริงๆ แล้วไม่มีใบรับรองการรับรองที่มีค่านี้ เนื่องจากในสถานะนี้โปรแกรมโหลดบูตจะหยุดทำงาน รวมไว้ที่นี่เพื่อความสมบูรณ์ สถานะนี้สอดคล้องกับสถานะการบูต สีแดง ตามที่ระบุไว้ในเอกสาร ประกอบขั้นตอนการบูตที่ตรวจสอบแล้ว |
ค่าระดับความปลอดภัย
ค่าของ securityLevel
มีความหมายดังต่อไปนี้:
ค่า | ความหมาย |
---|---|
Software | รหัสที่สร้างหรือจัดการองค์ประกอบที่เกี่ยวข้อง (เอกสารรับรองหรือคีย์) จะถูกนำไปใช้ในระบบ Android และอาจเปลี่ยนแปลงได้หากระบบนั้นถูกโจมตี |
TrustedEnvironment | รหัสที่สร้างหรือจัดการองค์ประกอบที่เกี่ยวข้อง (เอกสารรับรองหรือคีย์) จะถูกนำไปใช้ใน Trusted Execution Environment (TEE) อาจมีการเปลี่ยนแปลงได้หาก TEE ถูกบุกรุก แต่ TEE มีความทนทานสูงต่อการประนีประนอมจากระยะไกล และทนทานต่อการประนีประนอมจากการโจมตีด้วยฮาร์ดแวร์โดยตรงในระดับปานกลาง |
StrongBox | รหัสที่สร้างหรือจัดการองค์ประกอบที่เกี่ยวข้อง (เอกสารรับรองหรือคีย์) จะถูกนำไปใช้ในโมดูลความปลอดภัยของฮาร์ดแวร์เฉพาะ อาจมีการเปลี่ยนแปลงได้หากโมดูลความปลอดภัยของฮาร์ดแวร์ถูกบุกรุก แต่มีความทนทานสูงต่อการประนีประนอมจากระยะไกล และมีความทนทานสูงต่อการประนีประนอมจากการโจมตีด้วยฮาร์ดแวร์โดยตรง |
ID ไม่ซ้ำกัน
รหัสเฉพาะคือค่า 128 บิตที่ใช้ระบุอุปกรณ์ แต่ในระยะเวลาที่จำกัดเท่านั้น ค่าจะถูกคำนวณด้วย:
HMAC_SHA256(T || C || R, HBK)
ที่ไหน:
-
T
คือ "ค่าตัวนับชั่วคราว" ซึ่งคำนวณโดยการหารค่าของTag::CREATION_DATETIME
ด้วย 2592000000 โดยให้ทิ้งเศษที่เหลือT
เปลี่ยนทุกๆ 30 วัน (2592000000 = 30 * 24 * 60 * 60 * 1,000) -
C
คือค่าของTag::APPLICATION_ID
-
R
คือ 1 หากTag::RESET_SINCE_ID_ROTATION
มีอยู่ในพารามิเตอร์ attest_params ของการเรียก attest_key หรือ 0 หากไม่มีแท็ก -
HBK
เป็นความลับเฉพาะที่เชื่อมโยงกับฮาร์ดแวร์ซึ่งเป็นที่รู้จักใน Trusted Execution Environment และไม่เคยเปิดเผยโดยสิ่งนี้ ข้อมูลลับประกอบด้วยเอนโทรปีอย่างน้อย 128 บิตและไม่ซ้ำกันในแต่ละอุปกรณ์ (ความน่าจะเป็นที่ไม่ซ้ำใครเป็นที่ยอมรับได้เมื่อมีเอนโทรปี 128 บิต) HBK ควรได้มาจากวัสดุหลักที่หลอมรวมผ่าน HMAC หรือ AES_CMAC
ตัดทอนเอาต์พุต HMAC_SHA256 ให้เป็น 128 บิต
คีย์การรับรองและใบรับรอง
สองคีย์, หนึ่ง RSA และหนึ่ง ECDSA และห่วงโซ่ใบรับรองที่เกี่ยวข้อง ได้รับการจัดเตรียมอย่างปลอดภัยในอุปกรณ์
Android 12 เปิดตัวการจัดเตรียมคีย์ระยะไกล และ Android 13 กำหนดให้อุปกรณ์ใช้งาน การจัดเตรียมคีย์ระยะไกลมอบอุปกรณ์ในภาคสนามที่มีใบรับรองการรับรอง ECDSA P256 ต่อแอปพลิเคชัน ใบรับรองเหล่านี้มีอายุสั้นกว่าใบรับรองที่จัดเตรียมโดยโรงงาน
IMEI หลายรายการ
Android 14 เพิ่มการรองรับ IMEI หลายรายการในบันทึกการรับรองคีย์ Android OEM สามารถใช้คุณลักษณะนี้ได้โดยการเพิ่มแท็ก KeyMint สำหรับ IMEI ที่สอง เป็นเรื่องปกติมากขึ้นเรื่อยๆ สำหรับอุปกรณ์ที่มีวิทยุเซลลูลาร์หลายเครื่อง และขณะนี้ OEM สามารถรองรับอุปกรณ์ที่มี IMEI สองตัวได้
OEM จำเป็นต้องมี IMEI รอง หากมีอยู่ในอุปกรณ์ เพื่อจัดเตรียมการใช้งาน KeyMint เพื่อให้การใช้งานเหล่านั้นสามารถยืนยันได้ในลักษณะเดียวกับที่พวกเขายืนยันกับ IMEI แรก
การรับรองบัตรประจำตัว
Android 8.0 มีการสนับสนุนเพิ่มเติมสำหรับการรับรอง ID สำหรับอุปกรณ์ที่มี Keymaster 3 การรับรอง ID ช่วยให้อุปกรณ์สามารถแสดงหลักฐานตัวระบุฮาร์ดแวร์ เช่น หมายเลขซีเรียลหรือ IMEI แม้ว่าจะเป็นคุณสมบัติเสริม ขอแนะนำอย่างยิ่งให้การใช้งาน Keymaster 3 ทั้งหมดให้การสนับสนุน เนื่องจากความสามารถในการพิสูจน์ตัวตนของอุปกรณ์ทำให้กรณีการใช้งาน เช่น การกำหนดค่าระยะไกลแบบไม่ต้องสัมผัสที่แท้จริงมีความปลอดภัยมากขึ้น (เพราะด้านระยะไกลสามารถมั่นใจได้ กำลังพูดคุยกับอุปกรณ์ที่ถูกต้อง ไม่ใช่อุปกรณ์ที่ปลอมแปลงข้อมูลประจำตัว)
การรับรอง ID ทำงานโดยการสร้างสำเนาของตัวระบุฮาร์ดแวร์ของอุปกรณ์ที่เฉพาะ Trusted Execution Environment (TEE) เท่านั้นที่สามารถเข้าถึงได้ก่อนที่อุปกรณ์จะออกจากโรงงาน ผู้ใช้อาจปลดล็อกโปรแกรมโหลดบูตของอุปกรณ์และเปลี่ยนซอฟต์แวร์ระบบและตัวระบุที่รายงานโดยเฟรมเวิร์ก Android สำเนาของตัวระบุที่ TEE ถืออยู่ไม่สามารถจัดการได้ด้วยวิธีนี้ ทำให้มั่นใจได้ว่าการรับรอง ID อุปกรณ์จะรับรองเฉพาะตัวระบุฮาร์ดแวร์ดั้งเดิมของอุปกรณ์เท่านั้น จึงขัดขวางความพยายามในการปลอมแปลง
พื้นผิว API หลักสำหรับการรับรอง ID สร้างขึ้นจากกลไกการรับรองคีย์ที่มีอยู่ซึ่งนำมาใช้กับ Keymaster 2 เมื่อขอใบรับรองการรับรองสำหรับคีย์ที่มาสเตอร์ถือไว้ ผู้เรียกอาจขอให้รวมตัวระบุฮาร์ดแวร์ของอุปกรณ์ไว้ในข้อมูลเมตาของใบรับรองการรับรอง หากคีย์ถูกเก็บไว้ใน TEE ใบรับรองจะเชื่อมโยงกลับไปยังรูทของความไว้วางใจที่รู้จัก ผู้รับใบรับรองดังกล่าวสามารถตรวจสอบได้ว่าใบรับรองและเนื้อหาในนั้น รวมถึงตัวระบุฮาร์ดแวร์ เขียนโดย TEE เมื่อถูกขอให้รวมตัวระบุฮาร์ดแวร์ในใบรับรองการรับรอง TEE จะรับรองเฉพาะตัวระบุที่เก็บไว้ในที่จัดเก็บตามที่บรรจุอยู่บนพื้นโรงงาน
คุณสมบัติการจัดเก็บ
พื้นที่จัดเก็บข้อมูลที่เก็บตัวระบุอุปกรณ์จะต้องมีคุณสมบัติเหล่านี้:
- ค่าที่ได้รับจากตัวระบุดั้งเดิมของอุปกรณ์จะถูกคัดลอกไปยังที่จัดเก็บข้อมูลก่อนที่อุปกรณ์จะออกจากโรงงาน
- เมธอด
destroyAttestationIds()
สามารถทำลายสำเนาของข้อมูลที่ได้รับจากตัวระบุนี้อย่างถาวร การทำลายล้างอย่างถาวรหมายถึงข้อมูลจะถูกลบออกอย่างสมบูรณ์ ดังนั้นทั้งการรีเซ็ตเป็นค่าจากโรงงานหรือขั้นตอนอื่นใดที่ดำเนินการบนอุปกรณ์จะไม่สามารถกู้คืนได้ นี่เป็นสิ่งสำคัญอย่างยิ่งสำหรับอุปกรณ์ที่ผู้ใช้ปลดล็อคโปรแกรมโหลดบูตและเปลี่ยนซอฟต์แวร์ระบบและแก้ไขตัวระบุที่ส่งคืนโดยเฟรมเวิร์ก Android - สิ่งอำนวยความสะดวก RMA ควรมีความสามารถในการสร้างสำเนาใหม่ของข้อมูลที่ได้รับจากตัวระบุฮาร์ดแวร์ ด้วยวิธีนี้ อุปกรณ์ที่ผ่าน RMA จะสามารถดำเนินการรับรอง ID ได้อีกครั้ง กลไกที่ใช้โดยสิ่งอำนวยความสะดวก RMA จะต้องได้รับการปกป้องเพื่อให้ผู้ใช้ไม่สามารถเรียกใช้ได้ด้วยตนเอง เนื่องจากจะทำให้พวกเขาได้รับการรับรอง ID ที่ถูกปลอมแปลง
- ไม่มีรหัสอื่นใดนอกจากแอปที่เชื่อถือได้ของ Keymaster ใน TEE ที่สามารถอ่านข้อมูลที่ได้รับจากตัวระบุที่เก็บไว้ในที่จัดเก็บข้อมูล
- ที่เก็บข้อมูลมีหลักฐานการงัดแงะ: หากเนื้อหาของที่เก็บข้อมูลได้รับการแก้ไข TEE จะถือว่ามันเหมือนกับว่าสำเนาของเนื้อหาถูกทำลายและปฏิเสธความพยายามในการรับรอง ID ทั้งหมด ซึ่งดำเนินการโดยการลงนามหรือ MACing ที่เก็บข้อมูล ตามที่อธิบายไว้ด้านล่าง
- ที่เก็บข้อมูลไม่มีตัวระบุดั้งเดิม เนื่องจากการรับรอง ID เกี่ยวข้องกับการท้าทาย ผู้โทรจะระบุตัวระบุที่จะยืนยันเสมอ TEE เพียงแต่ต้องตรวจสอบว่าค่าเหล่านี้ตรงกับค่าที่มีอยู่เดิม การจัดเก็บแฮชที่ปลอดภัยของค่าดั้งเดิมแทนค่าจะทำให้สามารถตรวจสอบได้
การก่อสร้าง
หากต้องการสร้างการใช้งานที่มีคุณสมบัติตามรายการข้างต้น ให้จัดเก็บค่าที่ได้รับจาก ID ในโครงสร้าง S ต่อไปนี้ อย่าเก็บสำเนาของค่า ID อื่น ยกเว้นตำแหน่งปกติในระบบ ซึ่งเจ้าของอุปกรณ์อาจแก้ไขโดยการรูท:
S = D || HMAC(HBK, D)
ที่ไหน:
-
D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
-
HMAC
คือโครงสร้าง HMAC ที่มีแฮชที่ปลอดภัยที่เหมาะสม (แนะนำ SHA-256) -
HBK
คือคีย์ที่ผูกกับฮาร์ดแวร์ซึ่งไม่ได้ใช้เพื่อวัตถุประสงค์อื่นใด -
ID 1 ...ID n
คือค่า ID ดั้งเดิม การเชื่อมโยงค่าเฉพาะกับดัชนีเฉพาะนั้นขึ้นอยู่กับการใช้งาน เนื่องจากอุปกรณ์ที่แตกต่างกันจะมีจำนวนตัวระบุที่แตกต่างกัน -
||
แสดงถึงการต่อข้อมูล
เนื่องจากเอาต์พุต HMAC มีขนาดคงที่ จึงไม่จำเป็นต้องมีส่วนหัวหรือโครงสร้างอื่นเพื่อให้สามารถค้นหาแฮช ID แต่ละรายการหรือ HMAC ของ D นอกเหนือจากการตรวจสอบค่าที่ให้มาเพื่อดำเนินการรับรองแล้ว การใช้งานจำเป็นต้องตรวจสอบความถูกต้องของ S โดยแยก D ออกจาก S , คำนวณ HMAC(HBK, D) และเปรียบเทียบกับค่าใน S เพื่อตรวจสอบว่าไม่มีการแก้ไข/เสียหาย ID แต่ละรายการ นอกจากนี้ การใช้งานต้องใช้การเปรียบเทียบเวลาคงที่สำหรับองค์ประกอบ ID แต่ละรายการและการตรวจสอบความถูกต้องของ S เวลาในการเปรียบเทียบจะต้องคงที่โดยไม่คำนึงถึงจำนวน ID ที่ให้มา และการจับคู่ที่ถูกต้องของส่วนใด ๆ ของการทดสอบ
ตัวระบุฮาร์ดแวร์
การรับรอง ID รองรับตัวระบุฮาร์ดแวร์ต่อไปนี้:
- ชื่อแบรนด์ที่
Build.BRAND
ส่งคืนใน Android - ชื่ออุปกรณ์ตามที่
Build.DEVICE
ส่งคืนใน Android - ชื่อผลิตภัณฑ์ที่ส่งคืนโดย
Build.PRODUCT
ใน Android - ชื่อผู้ผลิต ตามที่
Build.MANUFACTURER
ส่งคืนใน Android - ชื่อรุ่นตามที่
Build.MODEL
ส่งคืนใน Android - หมายเลขซีเรียล
- IMEI ของวิทยุทั้งหมด
- MEID ของวิทยุทั้งหมด
เพื่อรองรับการรับรองรหัสอุปกรณ์ อุปกรณ์จะยืนยันตัวระบุเหล่านี้ อุปกรณ์ทั้งหมดที่ใช้ Android มีหกเครื่องแรกและจำเป็นสำหรับคุณสมบัตินี้ในการทำงาน หากอุปกรณ์มีวิทยุเซลลูลาร์ในตัว อุปกรณ์นั้นจะต้องรองรับการรับรอง IMEI และ/หรือ MEID ของวิทยุด้วย
มีการร้องขอการรับรอง ID โดยดำเนินการรับรองคีย์และรวมถึงตัวระบุอุปกรณ์เพื่อยืนยันในคำขอ ตัวระบุถูกแท็กเป็น:
-
ATTESTATION_ID_BRAND
-
ATTESTATION_ID_DEVICE
-
ATTESTATION_ID_PRODUCT
-
ATTESTATION_ID_MANUFACTURER
-
ATTESTATION_ID_MODEL
-
ATTESTATION_ID_SERIAL
-
ATTESTATION_ID_IMEI
-
ATTESTATION_ID_MEID
ตัวระบุที่จะยืนยันคือสตริงไบต์ที่เข้ารหัส UTF-8 รูปแบบนี้ใช้กับตัวระบุที่เป็นตัวเลขด้วย ตัวระบุแต่ละตัวที่จะยืนยันจะแสดงเป็นสตริงที่เข้ารหัส UTF-8
หากอุปกรณ์ไม่รองรับการรับรองรหัส (หรือก่อนหน้านี้มีการเรียกใช้ destroyAttestationIds()
และอุปกรณ์ไม่สามารถยืนยันรหัสได้อีกต่อไป) คำขอรับรองคีย์ใดๆ ที่มีแท็กเหล่านี้ตั้งแต่หนึ่งแท็กขึ้นไปจะล้มเหลวด้วย ErrorCode::CANNOT_ATTEST_IDS
หากอุปกรณ์รองรับการรับรอง ID และมีแท็กข้างต้นอย่างน้อยหนึ่งแท็กรวมอยู่ในคำขอการรับรองคีย์ TEE จะตรวจสอบตัวระบุที่มาพร้อมกับแต่ละแท็กตรงกับสำเนาของตัวระบุฮาร์ดแวร์ หากตัวระบุตั้งแต่หนึ่งตัวขึ้นไปไม่ตรงกัน การรับรองทั้งหมดจะล้มเหลวด้วย ErrorCode::CANNOT_ATTEST_IDS
ถูกต้องสำหรับแท็กเดียวกันที่จะใส่หลายครั้ง ข้อมูลนี้อาจเป็นประโยชน์ เช่น เมื่อยืนยัน IMEI: อุปกรณ์อาจมีวิทยุหลายเครื่องที่มี IMEI หลายเครื่อง คำขอรับรองจะใช้ได้หากค่าที่ให้มาพร้อมกับ ATTESTATION_ID_IMEI
แต่ละรายการตรงกับวิทยุรายการใดรายการหนึ่งของอุปกรณ์ เช่นเดียวกับแท็กอื่นๆ ทั้งหมด
หากการรับรองสำเร็จ รหัสที่ได้รับการรับรองจะถูกเพิ่มลงใน ส่วนขยายการรับรอง (OID 1.3.6.1.4.1.11129.2.1.17) ของใบรับรองการรับรองที่ออกให้ โดยใช้ สคีมาจากด้านบน การเปลี่ยนแปลงจากสคีมารับรอง Keymaster 2 เป็น ตัวหนา พร้อมความคิดเห็น
จาวา API
ส่วนนี้เป็นเพียงข้อมูลเท่านั้น ผู้นำไปใช้ Keymaster จะไม่ใช้หรือใช้ Java API สิ่งนี้มีไว้เพื่อช่วยให้ผู้ใช้งานเข้าใจว่าแอปพลิเคชันใช้คุณสมบัติอย่างไร ส่วนประกอบของระบบอาจใช้แตกต่างกัน ซึ่งเป็นสาเหตุว่าทำไมส่วนนี้จึงไม่ควรถือเป็นบรรทัดฐาน