กำหนดสิทธิ์ของแอปที่กำหนดเอง

เอกสารนี้อธิบายวิธีที่นักพัฒนาแอปใช้ฟีเจอร์ด้านความปลอดภัยที่ Android มีให้เพื่อกำหนดสิทธิ์ของตนเองได้ การกำหนดสิทธิ์ที่กำหนดเองช่วยให้แอปแชร์ทรัพยากรและความสามารถกับแอปอื่นๆ ได้ ดูข้อมูลเพิ่มเติมเกี่ยวกับสิทธิ์ได้ที่ภาพรวมของสิทธิ์

ฉากหลัง

Android เป็นระบบปฏิบัติการที่แยกสิทธิ์ ซึ่งแต่ละแอปจะทำงานด้วยข้อมูลประจำตัวของระบบที่แตกต่างกัน (รหัสผู้ใช้และรหัสกลุ่ม Linux) นอกจากนี้ เรายังแยกส่วนต่างๆ ของระบบออกเป็นอัตลักษณ์ที่แตกต่างกันด้วย Linux จึงแยกแอปออกจากกันและออกจากระบบ

แอปสามารถแสดงฟังก์ชันการทำงานของตนเองต่อแอปอื่นๆ ได้โดยการกำหนดสิทธิ์ ที่แอปอื่นๆ สามารถขอได้ นอกจากนี้ ยังกำหนดสิทธิ์ที่ จะพร้อมใช้งานโดยอัตโนมัติสำหรับแอปอื่นๆ ที่ลงชื่อด้วย ใบรับรองเดียวกันได้ด้วย

การลงนามแอป

APK ทั้งหมดต้องลงนามด้วยใบรับรอง ซึ่งมีคีย์ส่วนตัวที่นักพัฒนาแอปเป็นผู้ถือ ใบรับรองไม่ จำเป็นต้องได้รับการลงนามจากผู้ออกใบรับรอง แอป Android สามารถใช้ใบรับรองแบบ Self-signed ได้ ซึ่งเป็นเรื่องปกติ จุดประสงค์ของ ใบรับรองใน Android คือการแยกแยะผู้เขียนแอป ซึ่งจะช่วยให้ระบบ ให้หรือปฏิเสธการเข้าถึงสิทธิ์ระดับลายเซ็นแก่แอป และให้หรือปฏิเสธคำขอของแอปที่จะได้รับ ข้อมูลประจำตัว Linux เดียวกันกับแอปอื่น

ให้สิทธิ์ลายเซ็นหลังจากเวลาการผลิตอุปกรณ์

ตั้งแต่ Android 12 (API ระดับ 31) เป็นต้นไป แอตทริบิวต์ knownCerts สำหรับ สิทธิ์ระดับลายเซ็นจะช่วยให้คุณอ้างอิงค่าแฮชของใบรับรองการลงนามที่รู้จักได้ในเวลาที่ประกาศ

คุณประกาศแอตทริบิวต์ knownCerts และใช้แฟล็ก knownSigner ในแอตทริบิวต์ protectionLevel ของแอป สำหรับสิทธิ์ระดับลายเซ็นที่เฉพาะเจาะจงได้ จากนั้น ระบบจะ ให้สิทธิ์ดังกล่าวแก่แอปที่ขอ หากผู้ลงนามใน ลำดับการลงนามของแอปที่ขอ รวมถึงผู้ลงนามปัจจุบัน ตรงกับหนึ่งในแฮชที่ ประกาศไว้พร้อมกับสิทธิ์ในแอตทริบิวต์ knownCerts

ฟีเจอร์knownSignerช่วยให้อุปกรณ์และแอปสามารถให้สิทธิ์ลายเซ็นแก่ แอปอื่นๆ ได้โดยไม่ต้องลงนามในแอป ณ เวลาที่ผลิต และจัดส่งอุปกรณ์

รหัสผู้ใช้และการเข้าถึงไฟล์

ในเวลาที่ติดตั้ง Android จะกำหนดรหัสผู้ใช้ Linux ที่แตกต่างกันให้กับแต่ละแพ็กเกจ ข้อมูลประจำตัวจะคงที่ตลอดอายุการใช้งานของแพ็กเกจในอุปกรณ์นั้น ในอุปกรณ์อื่น แพ็กเกจเดียวกันอาจมี UID ที่แตกต่างกัน สิ่งสำคัญคือแต่ละแพ็กเกจต้องมี UID ที่แตกต่างกันในอุปกรณ์ที่กำหนด

เนื่องจากการบังคับใช้ความปลอดภัยเกิดขึ้นที่ระดับกระบวนการ โดยปกติแล้วโค้ดของแพ็กเกจ 2 แพ็กเกจจึงไม่สามารถทำงานในกระบวนการเดียวกันได้ เนื่องจากต้องทำงานในฐานะผู้ใช้ Linux ที่แตกต่างกัน

ระบบจะกำหนดรหัสผู้ใช้ของแอปนั้นๆ ให้กับข้อมูลใดก็ตามที่แอปจัดเก็บไว้ และโดยปกติแล้วแพ็กเกจอื่นๆ จะเข้าถึงข้อมูลดังกล่าวไม่ได้

ดูข้อมูลเพิ่มเติมเกี่ยวกับโมเดลความปลอดภัยของ Android ได้ที่ภาพรวมความปลอดภัยของ Android

กำหนดและบังคับใช้สิทธิ์

หากต้องการบังคับใช้สิทธิ์ของคุณเอง คุณต้องประกาศสิทธิ์เหล่านั้นใน AndroidManifest.xml ก่อนโดยใช้องค์ประกอบ <permission> อย่างน้อย 1 รายการ

รูปแบบการตั้งชื่อ

ระบบไม่อนุญาตให้แพ็กเกจหลายรายการประกาศ สิทธิ์ที่มีชื่อเดียวกัน เว้นแต่แพ็กเกจทั้งหมดจะลงนามด้วย ใบรับรองเดียวกัน หากแพ็กเกจประกาศสิทธิ์ ระบบจะไม่อนุญาตให้ผู้ใช้ติดตั้งแพ็กเกจอื่นๆ ที่มีชื่อสิทธิ์เดียวกันด้วย เว้นแต่แพ็กเกจเหล่านั้นจะลงนามด้วยใบรับรองเดียวกันกับแพ็กเกจแรก

เราขอแนะนำให้ใส่คำนำหน้าสิทธิ์ด้วยชื่อแพ็กเกจของแอปโดยใช้ การตั้งชื่อแบบย้อนกลับของโดเมน ตามด้วย .permission. และคำอธิบายความสามารถที่สิทธิ์นั้นแสดงใน รูปแบบ SNAKE_CASE ตัวพิมพ์ใหญ่ เช่น com.example.myapp.permission.ENGAGE_HYPERSPACE

การทำตามคำแนะนำนี้จะช่วยหลีกเลี่ยงการตั้งชื่อที่ซ้ำกันและช่วยระบุเจ้าของและความตั้งใจของสิทธิ์ที่กำหนดเองได้อย่างชัดเจน

ตัวอย่าง

เช่น แอปที่ต้องการควบคุมว่าแอปอื่นๆ ใดสามารถเริ่มกิจกรรมอย่างใดอย่างหนึ่งได้ สามารถประกาศสิทธิ์สำหรับการดำเนินการนี้ได้ดังนี้

<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example.myapp" >
    
    <permission
      android:name="com.example.myapp.permission.DEADLY_ACTIVITY"
      android:label="@string/permlab_deadlyActivity"
      android:description="@string/permdesc_deadlyActivity"
      android:permissionGroup="android.permission-group.COST_MONEY"
      android:protectionLevel="dangerous" />
    ...
</manifest>

ต้องระบุแอตทริบิวต์ protectionLevel และจะบอกระบบถึงวิธี แจ้งให้ผู้ใช้ทราบเกี่ยวกับแอปที่ต้องใช้สิทธิ์ หรือแอปที่สามารถ มีสิทธิ์ได้ ตามที่อธิบายไว้ในเอกสารที่ลิงก์

แอตทริบิวต์ android:permissionGroup เป็นแอตทริบิวต์ที่ไม่บังคับและใช้เพื่อช่วยให้ระบบแสดงสิทธิ์ แก่ผู้ใช้เท่านั้น ในกรณีส่วนใหญ่ คุณจะตั้งค่านี้เป็นกลุ่มระบบมาตรฐาน (แสดงอยู่ใน android.Manifest.permission_group) แม้ว่าคุณจะกำหนดกลุ่มด้วยตนเองได้ตามที่อธิบายไว้ในส่วนต่อไปนี้ เราขอแนะนำให้ใช้กลุ่มที่มีอยู่แล้ว เนื่องจากจะช่วยลดความซับซ้อนของ UI สิทธิ์ที่แสดงต่อผู้ใช้

คุณต้องระบุทั้งป้ายกำกับและคำอธิบายสำหรับสิทธิ์ ซึ่งเป็นทรัพยากรสตริงที่ผู้ใช้จะเห็นเมื่อ ดูรายการสิทธิ์ (android:label) หรือรายละเอียดเกี่ยวกับสิทธิ์เดียว (android:description) ป้ายกำกับนี้จะสั้น โดยมีคำอธิบาย 2-3 คำเกี่ยวกับฟังก์ชันการทำงานหลักที่สิทธิ์นั้นปกป้อง คำอธิบายคือประโยค 2 ประโยคที่อธิบายว่าสิทธิ์ดังกล่าวอนุญาตให้ผู้ถือทำอะไรได้บ้าง แบบแผนของเราคือคำอธิบาย 2 ประโยค โดยประโยคแรกอธิบาย สิทธิ์และประโยคที่ 2 เตือนผู้ใช้เกี่ยวกับประเภทของสิ่ง ที่อาจผิดพลาดหากแอปได้รับสิทธิ์

ตัวอย่างป้ายกำกับและคำอธิบายสำหรับสิทธิ์ CALL_PHONE มีดังนี้

<string name="permlab_callPhone">directly call phone numbers</string>
<string name="permdesc_callPhone">Allows the app to call non-emergency
phone numbers without your intervention. Malicious apps may cause unexpected
calls on your phone bill.</string>

สร้างกลุ่มสิทธิ์

ดังที่แสดงในส่วนก่อนหน้า คุณสามารถใช้แอตทริบิวต์ android:permissionGroup เพื่อช่วยให้ระบบอธิบาย สิทธิ์แก่ผู้ใช้ได้ ในกรณีส่วนใหญ่ คุณจะตั้งค่านี้เป็นกลุ่มระบบมาตรฐาน (แสดงอยู่ใน android.Manifest.permission_group) แต่คุณยังกำหนดกลุ่มของคุณเองได้ด้วย <permission-group>

องค์ประกอบ <permission-group> จะกำหนดป้ายกำกับสำหรับชุดสิทธิ์ ทั้งสิทธิ์ที่ประกาศในไฟล์ Manifest ด้วยองค์ประกอบ <permission> และสิทธิ์ที่ประกาศในที่อื่นๆ ซึ่งจะส่งผลต่อการจัดกลุ่มสิทธิ์เมื่อแสดงต่อผู้ใช้เท่านั้น องค์ประกอบ <permission-group> ไม่ได้ระบุสิทธิ์ที่เป็นของกลุ่ม แต่ จะตั้งชื่อให้กลุ่ม

คุณให้สิทธิ์ในกลุ่มได้โดยกำหนดชื่อกลุ่มให้กับแอตทริบิวต์ <permission> ขององค์ประกอบ permissionGroup

องค์ประกอบ <permission-tree> ประกาศเนมสเปซสำหรับกลุ่มสิทธิ์ที่กำหนดไว้ในโค้ด

คำแนะนำสิทธิ์ที่กำหนดเอง

คุณกำหนดสิทธิ์ที่กำหนดเองสำหรับแอปและขอสิทธิ์ที่กำหนดเอง จากแอปอื่นๆ ได้โดยกำหนดองค์ประกอบ <uses-permission> อย่างไรก็ตาม โปรดประเมินอย่างรอบคอบว่าจำเป็นต้องดำเนินการดังกล่าวหรือไม่

  • หากคุณกำลังออกแบบชุดแอปที่แสดงฟังก์ชันการทำงานต่อกัน ให้พยายามออกแบบแอปเพื่อให้กำหนดสิทธิ์แต่ละรายการเพียงครั้งเดียว คุณต้องดำเนินการนี้หากแอปไม่ได้ลงนามด้วยใบรับรองเดียวกันทั้งหมด แม้ว่าแอปทั้งหมดจะลงนามด้วยใบรับรองเดียวกัน แนวทางปฏิบัติแนะนำคือการกำหนดสิทธิ์แต่ละรายการเพียงครั้งเดียว
  • หากฟังก์ชันการทำงานใช้ได้เฉพาะกับแอปที่ลงนามด้วยลายเซ็นเดียวกันกับแอปที่ให้บริการ คุณอาจหลีกเลี่ยงการกำหนดสิทธิ์ที่กำหนดเองได้โดยใช้การตรวจสอบลายเซ็น เมื่อแอปหนึ่งของคุณส่งคำขอ ไปยังแอปอื่นของคุณ แอปที่ 2 จะยืนยันได้ว่าทั้ง 2 แอปได้รับการลงนาม ด้วยใบรับรองเดียวกันก่อนที่จะปฏิบัติตามคำขอ

หากจำเป็นต้องใช้สิทธิ์ที่กำหนดเอง ให้พิจารณาว่าเฉพาะแอปพลิเคชันที่ลงชื่อโดยนักพัฒนาแอปคนเดียวกับแอปพลิเคชันที่ตรวจสอบสิทธิ์เท่านั้นที่ต้องเข้าถึงสิทธิ์ดังกล่าวหรือไม่ เช่น เมื่อใช้การสื่อสารระหว่างกระบวนการที่ปลอดภัยระหว่างแอปพลิเคชัน 2 รายการจากนักพัฒนาแอปคนเดียวกัน หากใช่ เราขอแนะนำให้ใช้สิทธิ์ลายเซ็น สิทธิ์ลายเซ็นมีความโปร่งใสต่อผู้ใช้และหลีกเลี่ยงสิทธิ์ที่ผู้ใช้ยืนยัน ซึ่งอาจทำให้ผู้ใช้สับสน

อ่านข้อมูลเพิ่มเติมเกี่ยวกับ

<uses-permission>
ข้อมูลอ้างอิง API สำหรับแท็ก Manifest ที่ประกาศสิทธิ์ของระบบที่แอปของคุณต้องใช้

คุณอาจสนใจ

ภาพรวมการรักษาความปลอดภัยของ Android
การอภิปรายโดยละเอียดเกี่ยวกับโมเดลความปลอดภัยของแพลตฟอร์ม Android