เอกสารนี้อธิบายวิธีที่นักพัฒนาแอปสามารถใช้ ฟีเจอร์ความปลอดภัยที่ Android มีให้เพื่อกำหนดสิทธิ์ของตนเอง โดยการกำหนดสิทธิ์ที่กำหนดเอง แอปจะแชร์ทรัพยากรและความสามารถกับแอปอื่นๆ ได้ ดูข้อมูลเพิ่มเติมเกี่ยวกับสิทธิ์ได้ที่ภาพรวมสิทธิ์
ฉากหลัง
Android เป็นระบบปฏิบัติการที่มีการแยกสิทธิ์ ซึ่งแต่ละ แอปจะทำงานด้วยข้อมูลประจำตัวของระบบที่แตกต่างกัน (รหัสผู้ใช้และรหัสกลุ่ม Linux) นอกจากนี้ ระบบยังแยกส่วนต่างๆ ออกเป็นข้อมูลประจำตัวที่แตกต่างกันด้วย ด้วยเหตุนี้ Linux จึงแยกแอปออกจากกันและแยกแอปออกจากระบบ
แอปสามารถเปิดเผยฟังก์ชันการทำงานของตนเองให้แอปอื่นๆ ได้โดยการกำหนดสิทธิ์ ที่แอปอื่นๆ สามารถขอได้ นอกจากนี้ยังกำหนดสิทธิ์ที่ พร้อมใช้งานโดยอัตโนมัติสำหรับแอปอื่นๆ ที่ลงนามด้วย ใบรับรองเดียวกันได้ด้วย
App Signing
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 เตือนผู้ใช้เกี่ยวกับสิ่งต่างๆ ที่อาจเกิดขึ้นหากแอปได้รับสิทธิ์
ตัวอย่างป้ายกำกับและคำอธิบายสำหรับสิทธิ์
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