คีย์สโตร์แบบใช้ฮาร์ดแวร์

ความพร้อมใช้งานของสภาพแวดล้อมการดำเนินการที่เชื่อถือได้ในระบบบนชิป (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

รูปที่ 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 ในนโยบาย SELinux
  • DOMAIN_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 ต้องมีสิทธิ์นี้เพื่อพยายามปลดล็อกคีย์หลักสำหรับการตรวจสอบสิทธิ์ คีย์ที่เชื่อมโยง