เอกสารนี้อธิบายวิธีที่นักพัฒนาแอปใช้ฟีเจอร์ด้านความปลอดภัยที่ 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