ความพร้อมใช้งานของสภาพแวดล้อมการดำเนินการที่เชื่อถือได้ในระบบบนชิป (SoC) เปิดโอกาสให้อุปกรณ์ Android สนับสนุนฮาร์ดแวร์ บริการรักษาความปลอดภัยที่มีประสิทธิภาพสำหรับระบบปฏิบัติการ Android ไปจนถึงบริการของแพลตฟอร์ม แอปของบุคคลที่สาม นักพัฒนาซอฟต์แวร์ที่กำลังมองหาส่วนขยายสำหรับ Android โดยเฉพาะควรไปที่ ไปยัง android.security.keystore
ก่อน Android 6.0 Android มีคริปโตแบบเรียบง่ายที่ใช้ฮาร์ดแวร์อยู่แล้ว API ของบริการ ซึ่งมาจากเวอร์ชัน 0.2 และ 0.3 ของฮาร์ดแวร์ Keymaster Abstraction Layer (HAL) การลงนามและการยืนยันแบบดิจิทัลที่ได้รับจากคีย์สโตร์ การดำเนินการ รวมถึงการสร้างและนำเข้าคู่คีย์การลงชื่อแบบอสมมาตร นี่คือ บนอุปกรณ์ต่างๆ มากมาย แต่มีเป้าหมายด้านความปลอดภัยมากมาย ไม่สามารถทำได้ง่ายๆ ด้วย Signature API คีย์สโตร์ใน Android 6.0 ขยาย Keystore API เพื่อให้มีความสามารถที่หลากหลายมากขึ้น
เพิ่มคีย์สโตร์ใน Android 6.0 แล้ว แบบพื้นฐานที่เข้ารหัสแบบสมมาตร AES และ HMAC และระบบควบคุมการเข้าถึงสำหรับคีย์ที่สนับสนุนด้วยฮาร์ดแวร์ สิทธิ์เข้าถึง การควบคุมถูกระบุในระหว่างการสร้างคีย์และบังคับใช้ตลอดอายุการใช้งานของ คีย์ คีย์สามารถถูกจำกัดให้ใช้งานได้หลังจากผู้ใช้ ตรวจสอบสิทธิ์แล้ว และสำหรับวัตถุประสงค์ที่ระบุหรือด้วยการเข้ารหัสที่ระบุเท่านั้น พารามิเตอร์ สำหรับข้อมูลเพิ่มเติม โปรดดู แท็กการให้สิทธิ์ และ ฟังก์ชัน
นอกจากการขยายช่วงของ ดั้งเดิม การเข้ารหัสลับแล้ว คีย์สโตร์ใน Android 6.0 ได้เพิ่มสิ่งต่อไปนี้
- รูปแบบการควบคุมการใช้งานเพื่ออนุญาตให้ใช้งานคีย์ได้อย่างจำกัด เพื่อลด ความเสี่ยงที่จะถูกบุกรุกด้านความปลอดภัยเนื่องจากการใช้คีย์ในทางที่ผิด
- รูปแบบการควบคุมการเข้าถึงเพื่อเปิดใช้การจำกัดคีย์สำหรับผู้ใช้ที่ระบุ ลูกค้า และช่วงเวลาที่กำหนดไว้
ใน Android 7.0 Keymaster 2 เพิ่มการรองรับเอกสารรับรองและเวอร์ชันของคีย์ การผูก เอกสารรับรองคีย์ ให้ใบรับรองคีย์สาธารณะที่มีคำอธิบายคีย์อย่างละเอียด และการควบคุมการเข้าถึง เพื่อให้คีย์มีอยู่ในฮาร์ดแวร์ที่ปลอดภัย ที่ยืนยันการกำหนดค่าจากระยะไกลได้
การเชื่อมโยงเวอร์ชัน เชื่อมโยงคีย์กับระบบปฏิบัติการและเวอร์ชันระดับแพตช์ ซึ่งช่วยให้มั่นใจว่า ผู้โจมตีที่พบจุดอ่อนในระบบเวอร์ชันเก่าหรือ ซอฟต์แวร์ TEE ไม่สามารถย้อนกลับอุปกรณ์ไปยังเวอร์ชันที่มีช่องโหว่และใช้คีย์ได้ ที่สร้างขึ้นด้วยเวอร์ชันใหม่ นอกจากนี้ เมื่อคีย์ในเวอร์ชันที่กำหนด และใช้ระดับแพตช์ในอุปกรณ์ที่อัปเกรดเป็นเวอร์ชันใหม่กว่า หรือระดับแพตช์ คีย์จะได้รับการอัปเกรดก่อนที่จะใช้งานได้ ของคีย์ไม่ถูกต้อง เมื่ออุปกรณ์ได้รับการอัปเกรดแล้ว แป้น "ประแจ" ไปข้างหน้าพร้อมกับอุปกรณ์ แต่การเปลี่ยนอุปกรณ์กลับไป การปล่อยนี้จะทำให้คีย์ใช้งานไม่ได้
ใน Android 8.0 Keymaster 3 ได้เปลี่ยนจากฮาร์ดแวร์โครงสร้าง C แบบเก่า Abstraction Layer (HAL) ไปยังอินเทอร์เฟซ C++ HAL ที่สร้างขึ้นจากคำจำกัดความ ในภาษาฮาร์ดแวร์กำหนดอินเทอร์เฟซฮาร์ดแวร์ (HIDL) ใหม่ ส่วนหนึ่งของการเปลี่ยนแปลงนี้ ประเภทของอาร์กิวเมนต์มีการเปลี่ยนแปลงมากมาย แม้ว่าประเภทและเมธอดจะเป็นแบบ 1 ต่อ 1 การโต้ตอบกับประเภทเดิมและวิธีโครงสร้าง HAL โปรดดู หน้าฟังก์ชันสำหรับข้อมูลเพิ่มเติม รายละเอียด
นอกจากการแก้ไขอินเทอร์เฟซนี้ ยัง ฟีเจอร์เอกสารรับรองสำหรับการสนับสนุน เอกสารรับรองรหัส เอกสารรับรองรหัสมีกลไกที่จำกัดและไม่บังคับสำหรับการรับรองอย่างเข้มงวด กับตัวระบุฮาร์ดแวร์ เช่น หมายเลขซีเรียลของอุปกรณ์ ชื่อผลิตภัณฑ์ และโทรศัพท์ รหัส (IMEI / MEID) Android 8.0 ได้เปลี่ยน ASN.1 เพื่อใช้การเพิ่มนี้ สคีมาเอกสารรับรองเพื่อเพิ่มการรับรองรหัส การติดตั้งใช้งาน Keymaster จำเป็นต้องดำเนินการต่อไปนี้ หาวิธีที่ปลอดภัยในการเรียกรายการข้อมูลที่เกี่ยวข้อง รวมถึงกำหนด กลไกในการปิดใช้งานคุณลักษณะอย่างปลอดภัยและถาวร
การอัปเดตใน Android 9 มีดังนี้
- อัปเดตเป็น คีย์มาสเตอร์ 4
- การรองรับองค์ประกอบความปลอดภัยที่ฝังไว้
- รองรับการนำเข้าคีย์ความปลอดภัย
- การรองรับการเข้ารหัส 3DES
- การเปลี่ยนแปลงการเชื่อมโยงเวอร์ชันเพื่อให้ Boot.img และ system.img มี กำหนดเวอร์ชันแยกกันเพื่อให้อัปเดตได้โดยอิสระ
อภิธานศัพท์
ต่อไปนี้เป็นภาพรวมคร่าวๆ เกี่ยวกับคอมโพเนนต์ของคีย์สโตร์และความสัมพันธ์
AndroidKeystore คือ Android Framework API และคอมโพเนนต์ที่ใช้
ตามแอปพลิเคชันเพื่อเข้าถึงฟังก์ชันคีย์สโตร์ โดยใช้เป็นส่วนขยายเพื่อ
Java Cryptography Architecture API มาตรฐานและประกอบด้วยโค้ด Java ที่
ทำงานในพื้นที่การประมวลผลของแอปเอง AndroidKeystore
ดำเนินการตามแอป
คำขอสำหรับพฤติกรรมของคีย์สโตร์โดยส่งต่อไปยัง Daemon ของคีย์สโตร์
daemon ของคีย์สโตร์ คือดีมอนระบบ Android ที่ เข้าถึงฟังก์ชันการทำงานทั้งหมดของคีย์สโตร์ผ่าน Binder API ซึ่งมีหน้าที่จัดเก็บ "Key BLOB" มีเนื้อหาคีย์ลับจริงที่เข้ารหัสเพื่อให้ Keystore สามารถจัดเก็บ แต่ ไม่ใช้หรือเปิดเผย
keymasterd คือเซิร์ฟเวอร์ HIDL ที่ให้สิทธิ์เข้าถึง Keymaster TA (ชื่อนี้ไม่ได้เป็นมาตรฐานและใช้เพื่อจุดประสงค์ในเชิงแนวคิด)
Keymaster TA (แอปพลิเคชันที่เชื่อถือได้) คือซอฟต์แวร์ที่ทำงานใน บริบทที่ปลอดภัยซึ่งมักอยู่ใน TrustZone บน ARM SoC ที่ให้ การดำเนินการคีย์สโตร์ที่ปลอดภัย มีสิทธิ์เข้าถึงข้อมูลดิบของคีย์ ตรวจสอบ เงื่อนไขควบคุมการเข้าถึงกุญแจ เป็นต้น
LockSettingsService เป็นคอมโพเนนต์ระบบ Android
สำหรับการตรวจสอบสิทธิ์ผู้ใช้ ทั้งรหัสผ่านและลายนิ้วมือ ไม่ได้เป็นส่วนหนึ่งของ
คีย์สโตร์ แต่มีความเกี่ยวข้องเนื่องจากการดำเนินการคีย์สโตร์จำนวนมากต้องใช้ผู้ใช้
การตรวจสอบสิทธิ์ LockSettingsService
โต้ตอบกับผู้รับสายแทน
TA และ Fingerprint TA เท่านั้น เพื่อที่จะรับโทเค็นการตรวจสอบสิทธิ์
Daemon ของคีย์สโตร์ ซึ่งท้ายที่สุดแล้ว Keymaster TA จะใช้
แอปพลิเคชัน
TA ผู้รับสายแทน (แอปพลิเคชันที่เชื่อถือได้) เป็นอีกองค์ประกอบหนึ่ง ที่ทำงานในบริบทที่ปลอดภัย ซึ่งมีหน้าที่ในการตรวจสอบสิทธิ์ผู้ใช้ รหัสผ่านและสร้างโทเค็นการตรวจสอบสิทธิ์ที่ใช้เพื่อพิสูจน์ต่อ Keymaster TA ว่ามีการตรวจสอบสิทธิ์สำหรับผู้ใช้รายหนึ่งๆ ณ เวลาใดเวลาหนึ่งใน
ลายนิ้วมือ TA (แอปพลิเคชันที่เชื่อถือได้) เป็นอีกองค์ประกอบหนึ่ง ที่ทำงานในบริบทที่ปลอดภัยซึ่งมีหน้าที่ในการตรวจสอบสิทธิ์ผู้ใช้ ลายนิ้วมือและสร้างโทเค็นการตรวจสอบสิทธิ์ที่ใช้พิสูจน์กับ Keymaster ผู้ช่วยที่ว่าการตรวจสอบสิทธิ์กระทำสำหรับผู้ใช้คนใดคนหนึ่ง ณ จุดหนึ่ง ให้ทันเวลา
สถาปัตยกรรม
Android Keystore API และ Keymaster HAL ที่สำคัญ ให้ชุดการเข้ารหัสพื้นฐานที่เพียงพอเพื่อให้ การใช้งานโปรโตคอลโดยใช้คีย์ที่ควบคุมการเข้าถึงด้วยฮาร์ดแวร์
Keymaster HAL เป็นไลบรารีแบบโหลดแบบไดนามิกที่ได้จาก OEM ซึ่งใช้โดย บริการคีย์สโตร์ เพื่อให้บริการการเข้ารหัสลับโดยใช้ฮาร์ดแวร์ หากต้องการเก็บ ทั้งหมดมีความปลอดภัย การใช้งาน HAL จะไม่ดำเนินการที่ละเอียดอ่อนใดๆ พื้นที่ผู้ใช้ หรือแม้กระทั่งในพื้นที่เคอร์เนล การดำเนินการที่มีความละเอียดอ่อนจะมอบให้ ตัวประมวลผลที่ปลอดภัยซึ่งเข้าถึงผ่านอินเทอร์เฟซเคอร์เนลบางอย่าง สถาปัตยกรรมที่ได้จะมีลักษณะดังนี้
![สิทธิ์เข้าถึง Keymaster](https://source.android.com/static/docs/security/images/access-to-keymaster.png?authuser=0000&hl=th)
รูปที่ 1 สิทธิ์เข้าถึง Keymaster
ในอุปกรณ์ Android นั้น "ไคลเอ็นต์" HAL ของ Keymaster ประกอบด้วย หลายเลเยอร์ (เช่น แอป เฟรมเวิร์ก ดีมอนคีย์สโตร์) แต่อาจถูกละเว้น เพื่อวัตถุประสงค์ของเอกสารนี้ ซึ่งหมายความว่า HAL ของ Keymaster ที่อธิบายไว้ API อยู่ในระดับต่ำ ซึ่งใช้โดยคอมโพเนนต์ภายในแพลตฟอร์ม และไม่เปิดเผยต่อแอป รายละเอียดเกี่ยวกับ API ระดับสูงกว่าแสดงอยู่ในเว็บไซต์ของนักพัฒนาแอป Android
วัตถุประสงค์ของ Keymaster HAL คือไม่ใช่การใช้นโยบายที่คำนึงถึงความปลอดภัยเป็นหลัก แต่เป็นอัลกอริทึมของคำขอที่ส่งไปยังโลกที่ปลอดภัยเท่านั้น รูปแบบสายไฟคือชุดที่กำหนดไว้
ความเข้ากันได้กับรายการก่อนหน้า เวอร์ชัน
Keymaster 1 HAL ไม่เข้ากันกับ HAL ที่เผยแพร่ก่อนหน้านี้ เช่น Keymaster 0.2 และ 0.3 เพื่ออำนวยความสะดวก ความสามารถในการทำงานร่วมกันในอุปกรณ์ที่ใช้ Android 5.0 และเวอร์ชันก่อนหน้าที่เปิดตัวด้วย HAL ของ Keymaster แบบเก่า Keystore จะมีอะแดปเตอร์ที่ใช้ Keymaster 1 HAL ที่มีการเรียกไปยังไลบรารีฮาร์ดแวร์ที่มีอยู่ ผลลัพธ์ไม่สามารถ จะมีฟังก์ชันการทำงานที่หลากหลายใน Keymaster 1 HAL โดยเฉพาะอย่างยิ่ง แต่รองรับเฉพาะอัลกอริทึม RSA และ ECDSA และการให้สิทธิ์คีย์ทั้งหมด การบังคับใช้จะดำเนินการโดยอะแดปเตอร์ในโลกที่ไม่ปลอดภัย
Keymaster 2 ช่วยให้อินเทอร์เฟซ HAL ง่ายขึ้นโดยนำ
get_supported_*
วิธีและการอนุญาต finish()
วิธีการยอมรับการป้อนข้อมูล เพื่อลดจำนวนการเดินทางไป-กลับไปยัง TEE ใน
ในกรณีที่มีอินพุตพร้อมใช้งาน ทั้งหมดในครั้งเดียว และทำให้การนำไปใช้งาน
การถอดรหัส AEAD
ใน Android 8.0 Keymaster 3 ได้เปลี่ยนจากโครงสร้าง C แบบเก่า
HAL ไปยังอินเทอร์เฟซ HAL ของ C++ ที่สร้างขึ้นจากคำจำกัดความใน
ฮาร์ดแวร์ Interface Definition Language (HIDL) HAL รูปแบบใหม่
เกิดขึ้นโดยการแยกประเภทย่อย
IKeymasterDevice
และนำระบบเสมือนจริงทั้งหมดไปใช้
ในการเปลี่ยนแปลงนี้ อาร์กิวเมนต์หลายประเภทได้มีการเปลี่ยนแปลง
แต่ประเภทและวิธีการต่างๆ จะมีการโต้ตอบแบบหนึ่งต่อหนึ่งกับ
และวิธีโครงสร้าง HAL
ภาพรวม HIDL
ฮาร์ดแวร์อินเทอร์เฟซคำจำกัดความภาษา (ฮาร์ดแวร์ HIDL) ทำให้เกิดการใช้ กลไกการระบุอินเทอร์เฟซของฮาร์ดแวร์ที่ไม่ขึ้นอยู่กับภาษา HIDL ขณะนี้เครื่องมือสนับสนุนการสร้างอินเทอร์เฟซ C++ และ Java คาดว่าจะเป็น ว่าผู้ติดตั้งใช้งานสภาพแวดล้อมการดำเนินการที่เชื่อถือได้ (TEE) ส่วนใหญ่จะพบกับ C++ เครื่องมือที่สะดวกยิ่งขึ้น ดังนั้น เอกสารฉบับนี้จึงกล่าวถึงเฉพาะการนำเสนอ C++ เท่านั้น
อินเทอร์เฟซ HIDL ประกอบด้วยชุดวิธีการดังต่อไปนี้
methodName(INPUT ARGUMENTS) generates (RESULT ARGUMENTS);
ที่กำหนดไว้ล่วงหน้ามีหลายประเภท และ HAL ก็สามารถกำหนดการแจกแจงใหม่ ประเภทโครงสร้าง ดูรายละเอียดเพิ่มเติมเกี่ยวกับ HIDL ได้ที่ส่วนข้อมูลอ้างอิง
ตัวอย่างเมธอดจาก Keymaster 3 IKeymasterDevice.hal
มีดังนี้
generateKey(vec<KeyParameter> keyParams) generates(ErrorCode error, vec<uint8_t> keyBlob, KeyCharacteristics keyCharacteristics);
ค่านี้เทียบเท่ากับค่าต่อไปนี้จาก keymaster2 HAL
keymaster_error_t (*generate_key)( const struct keymaster2_device* dev, const keymaster_key_param_set_t* params, keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t* characteristics);
ในเวอร์ชัน HIDL อาร์กิวเมนต์ dev
ถูกนำออกเนื่องจาก
โดยปริยาย อาร์กิวเมนต์ params
ไม่ใช่โครงสร้างที่มี
ตัวชี้อ้างอิงอาร์เรย์ของออบเจ็กต์ key_parameter_t
แต่
vec
(เวกเตอร์) ที่มีวัตถุ KeyParameter
รายการ
ค่าที่ส่งคืนจะแสดงอยู่ในช่อง "generates
" รวมทั้ง
เวกเตอร์ของค่า uint8_t
สำหรับ BLOB คีย์
เมธอด C++ เสมือนจริงที่คอมไพเลอร์ HIDL สร้างขึ้นคือ
Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams, generateKey_cb _hidl_cb) override;
โดยที่ generateKey_cb
คือตัวชี้ฟังก์ชันตามที่กำหนดไว้ดังนี้
std::function<void(ErrorCode error, const hidl_vec<uint8_t>& keyBlob, const KeyCharacteristics& keyCharacteristics)>
กล่าวคือ generateKey_cb
คือฟังก์ชันที่ใช้ค่าที่ส่งกลับ
ที่ระบุไว้ในวลีสร้าง คลาสการใช้งาน HAL จะลบล้างค่านี้
เมธอด generateKey
และเรียกฟังก์ชัน generateKey_cb
เพื่อส่งคืนผลลัพธ์ของการดำเนินการให้กับผู้โทร จดฟังก์ชันนี้ไว้
การเรียกตัวชี้เป็นแบบพร้อมกัน ผู้โทรโทรหา
generateKey
และ generateKey
เรียกใช้ฟิลด์
ตัวชี้ฟังก์ชัน ซึ่งจะดำเนินการจนเสร็จสิ้น โดยส่งการควบคุมกลับไปยังฟังก์ชัน
generateKey
ซึ่งจะส่งกลับไปยังผู้โทร
ดูตัวอย่างโดยละเอียดได้จากการใช้งานเริ่มต้นใน
hardware/interfaces/keymaster/3.0/default/KeymasterDevice.cpp
การใช้งานเริ่มต้นจะให้ความเข้ากันได้แบบย้อนหลังสำหรับอุปกรณ์ที่มี
รูปแบบเก่า keymaster0, keymaster1 หรือ keymaster2 HALS
การควบคุมการเข้าถึง
กฎพื้นฐานที่สุดของการควบคุมการเข้าถึงคีย์สโตร์ก็คือ แต่ละแอปพลิเคชัน เนมสเปซของตนเอง แต่กฎทุกข้อมีข้อยกเว้น มีคีย์สโตร์อยู่ แผนที่แบบฮาร์ดโค้ดซึ่งทำให้ส่วนประกอบของระบบบางอย่างสามารถเข้าถึง Namespace นี่เป็นเครื่องมือที่ทื่อตรงที่ให้ส่วนประกอบหนึ่ง ควบคุมเนมสเปซอื่นโดยสมบูรณ์ จากนั้นก็เป็นเรื่องของผู้ให้บริการ ในฐานะไคลเอ็นต์ของคีย์สโตร์ ขณะนี้เรายังไม่มีวิธีเริ่มต้น เนมสเปซของคอมโพเนนต์ผู้ให้บริการ เช่น ผู้สมัคร WPA
เพื่อรองรับคอมโพเนนต์ของผู้ให้บริการและทำให้การควบคุมการเข้าถึงเป็นไปในทิศทางเดียวกัน ไม่มีข้อยกเว้นแบบฮาร์ดโค้ด Keystore 2.0 แนะนำโดเมนและ SELinux Namespace
โดเมนคีย์สโตร์
เราสามารถแยกเนมสเปซจาก UID ได้ด้วยโดเมนคีย์สโตร์ ลูกค้า การเข้าถึงคีย์ในคีย์สโตร์ต้องระบุโดเมน เนมสเปซ และชื่อแทน ที่ตนต้องการเข้าถึง จาก Tuple นี้และข้อมูลระบุตัวตนของผู้โทรที่เรา สามารถระบุแป้นที่ผู้โทรต้องการเข้าถึงและดูว่ามีรหัสที่เหมาะสมหรือไม่ สิทธิ์
เราเปิดตัวพารามิเตอร์โดเมน 5 รายการซึ่งใช้ควบคุมวิธีเข้าถึงคีย์ ตัวควบคุมนี้จะควบคุมความหมายของพารามิเตอร์เนมสเปซของตัวบอกคีย์และ การควบคุมการเข้าถึง
DOMAIN_APP
: โดเมนแอปครอบคลุม ลักษณะการทำงานเดิม Java Keystore SPI ใช้โดเมนนี้โดยค่าเริ่มต้น เมื่อใด ระบบจะไม่สนใจอาร์กิวเมนต์เนมสเปซ และ UID ของผู้โทร ใช้แทน การเข้าถึงโดเมนนี้ถูกควบคุมโดยป้ายกำกับ Keystore เพื่อเข้าถึง คลาสkeystore_key
ในนโยบาย SELinuxDOMAIN_SELINUX
: โดเมนนี้จะระบุว่า Namespace มีป้ายกำกับในนโยบาย SELinux ค้นหาพารามิเตอร์เนมสเปซแล้ว และแปลงเป็นบริบทเป้าหมาย และดำเนินการตรวจสอบสิทธิ์สำหรับ บริบทการเรียกใช้ SELinux สำหรับคลาสkeystore_key
เมื่อ สิทธิ์สำหรับการดำเนินการที่กำหนด จะมีการใช้ Tuple แบบเต็ม สำหรับการค้นหาคีย์DOMAIN_GRANT
: โดเมนการให้สิทธิ์ระบุว่า พารามิเตอร์เนมสเปซคือตัวระบุที่ให้สิทธิ์ ระบบจะไม่สนใจพารามิเตอร์ชื่อแทน การตรวจสอบ SELinux จะดำเนินการเมื่อมีการสร้างการให้สิทธิ์ การควบคุมการเข้าถึงเพิ่มเติม ตรวจสอบว่า UID ผู้โทรตรงกับ UID ผู้รับของการให้สิทธิ์ที่ขอเท่านั้นDOMAIN_KEY_ID
: โดเมนนี้จะระบุว่า พารามิเตอร์เนมสเปซคือรหัสคีย์ที่ไม่ซ้ำกัน อาจมีการสร้างคีย์ขึ้น ด้วยDOMAIN_APP
หรือDOMAIN_SELINUX
สิทธิ์ ดำเนินการตรวจสอบหลังจากdomain
และnamespace
โหลดจากฐานข้อมูลคีย์ในลักษณะเดียวกับการโหลด BLOB ตามโดเมน เนมสเปซ และ Tuple ที่เป็นชื่อแทน เหตุผลสำหรับโดเมนรหัสคีย์ ก็คือความต่อเนื่อง เมื่อเข้าถึงคีย์ด้วยชื่อแทน การเรียกครั้งต่อๆ มาอาจดำเนินการใน คีย์ที่แตกต่างกัน เนื่องจากอาจมีการสร้างหรือนำเข้าและเชื่อมโยงคีย์ใหม่ ชื่อแทนนี้ แต่รหัสคีย์จะไม่เปลี่ยนแปลง ดังนั้นเมื่อใช้คีย์ตามรหัสคีย์ หลังจากโหลดจากฐานข้อมูล Keystore โดยใช้ชื่อแทน 1 ครั้ง จึงมั่นใจได้ว่าจะเป็นคีย์เดียวกันตราบใดที่รหัสคีย์นั้นยังคงมีอยู่ ช่วงเวลานี้ ที่นักพัฒนาแอปไม่แสดง แต่ใช้ภายใน Android Keystore SPI เพื่อมอบประสบการณ์การใช้งานที่สอดคล้องกันมากขึ้นแม้ในขณะที่ใช้งาน เกิดขึ้นพร้อมกันอย่างไม่ปลอดภัยDOMAIN_BLOB
: โดเมน BLOB ระบุว่า ผู้โทรจะจัดการ BLOB ด้วยตัวเอง ตัวเลือกนี้ใช้สำหรับลูกค้าที่ต้องการ เข้าถึงคีย์สโตร์ก่อนที่จะต่อเชื่อมพาร์ติชันข้อมูล BLOB หลักคือ ซึ่งรวมอยู่ในฟิลด์blob
ของคำอธิบายคีย์
การใช้โดเมน SELinux เราสามารถให้คอมโพเนนต์ของผู้ให้บริการเข้าถึง เนมสเปซของคีย์สโตร์ที่เฉพาะเจาะจง ซึ่งคอมโพเนนต์ของระบบสามารถแชร์ได้ เช่น กล่องโต้ตอบการตั้งค่า
นโยบาย SELinux สำหรับ keystore_key
กำหนดค่าป้ายกำกับเนมสเปซโดยใช้ keystore2_key_context
แต่ละบรรทัดในไฟล์เหล่านี้จะจับคู่รหัสเนมสเปซที่เป็นตัวเลขกับป้ายกำกับ SELinux
ตัวอย่างเช่น
# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and # Settings to share keystore keys. 102 u:object_r:wifi_key:s0
หลังจากตั้งค่าเนมสเปซของคีย์ใหม่ด้วยวิธีนี้ เราจะสามารถให้สิทธิ์เข้าถึงได้
โดยเพิ่มนโยบายที่เหมาะสม เช่น เพื่อให้
wpa_supplicant
เพื่อรับและใช้คีย์ในเนมสเปซใหม่
เพิ่มบรรทัดต่อไปนี้ใน hal_wifi_supplicant.te
:
allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };
หลังจากตั้งค่าเนมสเปซใหม่ คุณสามารถใช้ AndroidKeyStore เกือบจะเป็น
ตามปกติ ความแตกต่างเพียงอย่างเดียวคือต้องระบุรหัสเนมสเปซ สำหรับ
การโหลดและการนำเข้าคีย์จากและไปยังคีย์สโตร์ จะมีการระบุรหัสเนมสเปซ
โดยใช้ AndroidKeyStoreLoadStoreParameter
ตัวอย่างเช่น
import android.security.keystore2.AndroidKeyStoreLoadStoreParameter; import java.security.KeyStore; KeyStore keystore = KeyStore.getInstance("AndroidKeyStore"); keystore.load(new AndroidKeyStoreLoadStoreParameter(102));
หากต้องการสร้างคีย์ในเนมสเปซที่กำหนด คุณต้องระบุรหัสเนมสเปซ
กำลังใช้ KeyGenParameterSpec.Builder#setNamespace():
import android.security.keystore.KeyGenParameterSpec; KeyGenParameterSpec.Builder specBuilder = new KeyGenParameterSpec.Builder(); specBuilder.setNamespace(102);
สามารถใช้ไฟล์บริบทต่อไปนี้เพื่อกำหนดค่า Keystore 2.0 SELinux Namespace แต่ละพาร์ติชันมีช่วงเนมสเปซที่สงวนไว้ต่างกัน 10,000 รายการ เพื่อหลีกเลี่ยงการชนกัน
พาร์ติชัน | ช่วง | ไฟล์การกำหนดค่า |
---|---|---|
ระบบ | 0 ... 9,999 เครื่อง | /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts |
ระบบที่ขยาย | 10,000 ... 19,999 คน | /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts |
ผลิตภัณฑ์ | 20,000 ... 29,999 คน | /product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts |
ตัวแทนจำหน่ายรายย่อย | 30,000 ... 39,999 คน | /vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts |
ไคลเอ็นต์ขอคีย์ด้วยการขอโดเมน SELinux และโดเมนที่คุณต้องการ
เนมสเปซเสมือน ซึ่งในกรณีนี้คือ "wifi_key"
ตามรหัสตัวเลข
ซึ่งสูงกว่าข้างต้น มีการกำหนดเนมสเปซต่อไปนี้ หากมีการแทนที่ ตารางต่อไปนี้จะระบุ UID ที่ใช้เพื่อให้สอดคล้องกับกฎพิเศษ เป็น
รหัส Namespace | ป้ายกำกับ SEPolicy | UID | คำอธิบาย |
---|---|---|---|
0 | คีย์ su | ไม่มี | คีย์ผู้ใช้ขั้นสูง ใช้สำหรับการทดสอบในบิลด์การแก้ไขข้อบกพร่องและวิศวกรเท่านั้น ไม่ใช่ ที่เกี่ยวข้องกับบิลด์ของผู้ใช้ |
1 | คีย์ Shell | ไม่มี | เนมสเปซที่ใช้ได้สำหรับ Shell ส่วนใหญ่ใช้สำหรับการทดสอบ แต่สามารถใช้กับ บิลด์ของผู้ใช้จากบรรทัดคำสั่งได้ |
100 | คีย์ Vold | ไม่มี | มีไว้เพื่อใช้โดย vold |
101 | คีย์ Osing | ไม่มี | ใช้โดย Daemon ที่ลงชื่อในอุปกรณ์ |
102 | คีย์ Wi-Fi | AID_WIFI(1010) | ใช้โดยระบบ Wifi ของ Android ซึ่งรวมถึง wpa_supplicant |
120 | เรซูเม่_เปิด_คีย์_รีบูต | AID_SYSTEM(1,000) | ใช้โดยเซิร์ฟเวอร์ระบบของ Android เพื่อรองรับการดำเนินการต่อเมื่อรีบูต |
เวกเตอร์การเข้าถึง
คลาส SELinux keystore_key
มีอายุค่อนข้างเก่าและบางส่วน
สิทธิ์ เช่น verify
หรือ sign
หายไป
ความหมาย สิทธิ์ชุดใหม่มีดังนี้ keystore2_key
ที่คีย์สโตร์ 2.0 จะบังคับใช้
สิทธิ์ | ความหมาย |
---|---|
delete
|
ตรวจสอบเมื่อนำคีย์ออกจากคีย์สโตร์ |
get_info
|
เลือกเมื่อมีการขอข้อมูลเมตาของคีย์ |
grant
|
ผู้โทรต้องมีสิทธิ์นี้เพื่อสร้างการให้สิทธิ์คีย์ในเป้าหมาย บริบท |
manage_blob
|
ผู้โทรอาจใช้ DOMAIN_BLOB ในเนมสเปซ SELinux ที่ระบุ
ดังนั้นจึงสามารถจัดการ BLOB ได้ด้วยตัวเอง ซึ่งมีประโยชน์อย่างยิ่งสำหรับ
Vold |
rebind
|
สิทธิ์นี้ควบคุมว่าชื่อแทนจะกลับสู่คีย์ใหม่ได้หรือไม่ นี่คือ ที่จำเป็นสำหรับการแทรก และบอกเป็นนัยว่าคีย์ที่เชื่อมโยงก่อนหน้านี้จะ ลบแล้ว โดยพื้นฐานแล้วว่าเป็นสิทธิ์การแทรก แต่จะสามารถจับความหมายของ ของคีย์สโตร์ได้ดีขึ้น |
req_forced_op
|
ไคลเอ็นต์ที่มีสิทธิ์นี้อาจสร้างการดำเนินการที่ไม่สามารถดำเนินการได้ และ การสร้างการดำเนินการจะไม่ล้มเหลวเว้นแต่สล็อตการดำเนินการทั้งหมดจะดำเนินการโดย ที่ไม่สามารถดำเนินการได้ |
update
|
จำเป็นต้องอัปเดตคอมโพเนนต์ย่อยของคีย์ |
use
|
เลือกไว้เมื่อสร้างการดำเนินการ Keymint ที่ใช้เนื้อหาคีย์ เช่น สำหรับการลงชื่อ การเข้ารหัส/การถอดรหัส |
use_dev_id
|
ต้องระบุเมื่อสร้างข้อมูลที่ระบุอุปกรณ์ เช่น รหัสอุปกรณ์ และการรับรอง |
นอกจากนี้ เรายังได้แยกชุดสิทธิ์ของคีย์สโตร์ที่ไม่เจาะจงคีย์ไว้ใน
คลาสความปลอดภัย SELinux keystore2
:
สิทธิ์ | ความหมาย |
---|---|
add_auth
|
ต้องดำเนินการโดยผู้ให้บริการตรวจสอบสิทธิ์ เช่น Gatekeeper หรือ BiometricsManager สำหรับการเพิ่มโทเค็นการตรวจสอบสิทธิ์ |
clear_ns
|
ก่อนหน้านี้ clear_uid สิทธิ์นี้อนุญาตให้ผู้ที่ไม่ใช่เจ้าของเนมสเปซ ลบคีย์ทั้งหมดในเนมสเปซนั้น |
list
|
ระบบต้องใช้สำหรับการระบุคีย์ตามคุณสมบัติต่างๆ เช่น
ความเป็นเจ้าของหรือขอบเขตการตรวจสอบสิทธิ์ ผู้โทรไม่จำเป็นต้องใช้สิทธิ์นี้
แจกแจงเนมสเปซของตนเอง ซึ่งอยู่ภายใต้
สิทธิ์get_info |
lock
|
สิทธิ์นี้ทำให้สามารถล็อกคีย์สโตร์ กล่าวคือ ปลดคีย์หลักออก เช่น คีย์ที่เชื่อมโยงกับการตรวจสอบสิทธิ์นั้นจะใช้งานไม่ได้และจะสร้างไม่ได้ |
reset
|
สิทธิ์นี้อนุญาตให้รีเซ็ตคีย์สโตร์เป็นค่าเริ่มต้นจากโรงงาน โดยจะลบทั้งหมด ที่ไม่จำเป็นต่อการทำงานของระบบปฏิบัติการ Android |
unlock
|
ต้องมีสิทธิ์นี้เพื่อพยายามปลดล็อกคีย์หลักสำหรับการตรวจสอบสิทธิ์ คีย์ที่เชื่อมโยง |