In diesem Dokument wird beschrieben, wie App-Entwickler die von Android bereitgestellten Sicherheitsfunktionen verwenden können, um eigene Berechtigungen zu definieren. Durch das Definieren benutzerdefinierter Berechtigungen kann eine App ihre Ressourcen und Funktionen für andere Apps freigeben. Weitere Informationen zu Berechtigungen finden Sie in der Übersicht zu Berechtigungen.
Hintergrund
Android ist ein Betriebssystem mit Berechtigungstrennung, in dem jede App mit einer eigenen Systemidentität (Linux-Nutzer-ID und Gruppen ID) ausgeführt wird. Auch Teile des Systems sind in separate Identitäten unterteilt. Linux isoliert Apps so voneinander und vom System.
Apps können ihre Funktionen für andere Apps freigeben, indem sie Berechtigungen definieren, die andere Apps anfordern können. Sie können auch Berechtigungen definieren, die automatisch für alle anderen Apps verfügbar gemacht werden, die mit demselben Zertifikat signiert sind.
App-Signatur
Alle APKs müssen mit einem Zertifikat signiert sein, dessen privater Schlüssel vom Entwickler verwaltet wird. Das Zertifikat muss nicht von einer Zertifizierungsstelle signiert sein. Es ist zulässig und üblich, dass Android-Apps selbst signierte Zertifikate verwenden. Zertifikate dienen in Android dazu, App-Autoren zu unterscheiden. So kann das System Apps Zugriff auf Berechtigungen auf Signatur-Ebene gewähren oder verweigern und die Anfrage einer App, dieselbe Linux-Identität wie eine andere App zu erhalten, gewähren oder verweigern.
Signaturberechtigungen nach der Geräteherstellung gewähren
Ab Android 12 (API-Level 31) können Sie mit dem
knownCerts Attribut für
Berechtigungen auf Signatur-Ebene zur Deklarationszeit auf die Digests bekannter Signatur
zertifikate verweisen.
Sie können das Attribut knownCerts deklarieren und das Flag knownSigner
im Attribut protectionLevel
Ihrer App
für eine bestimmte Berechtigung auf Signatur-Ebene verwenden. Das System gewährt diese Berechtigung dann einer anfragenden App, wenn ein Unterzeichner in der Signaturkette der anfragenden App, einschließlich des aktuellen Unterzeichners, mit einem der Digests übereinstimmt, die mit der Berechtigung im Attribut knownCerts deklariert wurden.
Mit dem Flag knownSigner können Geräte und Apps anderen Apps Signaturberechtigungen gewähren, ohne die Apps zum Zeitpunkt der Geräteherstellung und des Versands signieren zu müssen.
Nutzer-IDs und Dateizugriff
Bei der Installation weist Android jedem Paket eine eindeutige Linux-Nutzer-ID zu. Die Identität bleibt für die gesamte Lebensdauer des Pakets auf diesem Gerät konstant. Auf einem anderen Gerät kann dasselbe Paket eine andere UID haben. Wichtig ist, dass jedes Paket auf einem bestimmten Gerät eine eindeutige UID hat.
Da die Sicherheitsdurchsetzung auf Prozessebene erfolgt, kann der Code von zwei Paketen normalerweise nicht im selben Prozess ausgeführt werden, da sie als unterschiedliche Linux-Nutzer ausgeführt werden müssen.
Alle von einer App gespeicherten Daten werden der Nutzer ID dieser App zugewiesen und sind normalerweise für andere Pakete nicht zugänglich.
Weitere Informationen zum Sicherheitsmodell von Android finden Sie in der Android-Sicherheits übersicht.
Berechtigungen definieren und erzwingen
Wenn Sie Ihre eigenen Berechtigungen erzwingen möchten, müssen Sie sie zuerst in Ihrer
AndroidManifest.xml mit einem oder mehreren
<permission>-Elementen deklarieren.
Namenskonvention
Das System lässt nicht zu, dass mehrere Pakete eine Berechtigung mit demselben Namen deklarieren, es sei denn, alle Pakete sind mit demselben Zertifikat signiert. Wenn ein Paket eine Berechtigung deklariert, lässt das System auch nicht zu, dass der Nutzer andere Pakete mit demselben Berechtigungsnamen installiert, es sei denn, diese Pakete sind mit demselben Zertifikat wie das erste Paket signiert.
Wir empfehlen, Berechtigungen mit dem Paketnamen einer App zu präfixieren. Verwenden Sie dabei die Namenskonvention für umgekehrte Domains, gefolgt von .permission. und dann einer Beschreibung der Funktion, die die Berechtigung darstellt, in SNAKE_CASE. Beispiel: com.example.myapp.permission.ENGAGE_HYPERSPACE.
Wenn Sie dieser Empfehlung folgen, vermeiden Sie Namenskonflikte und können den Inhaber und die Absicht einer benutzerdefinierten Berechtigung klar identifizieren.
Beispiel
Eine App, die steuern muss, welche anderen Apps eine ihrer Aktivitäten starten können, kann beispielsweise eine Berechtigung für diesen Vorgang so deklarieren:
<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>
Das Attribut
protectionLevel ist erforderlich und gibt dem System an, wie Nutzer über Apps informiert werden sollen, die die Berechtigung benötigen, oder welche Apps die Berechtigung haben können, wie in der verlinkten Dokumentation beschrieben.
Das android:permissionGroup
Attribut ist optional und wird nur verwendet, um dem System zu helfen, Berechtigungen
für den Nutzer anzuzeigen. In den meisten Fällen legen Sie dies auf eine Standard-Systemgruppe fest (aufgelistet in android.Manifest.permission_group). Sie können aber auch selbst eine Gruppe definieren, wie im folgenden Abschnitt beschrieben.
Wir empfehlen, eine vorhandene Gruppe zu verwenden, da dies die Berechtigungs-UI vereinfacht, die dem Nutzer angezeigt wird.
Sie müssen sowohl ein Label als auch eine Beschreibung für die
Berechtigung angeben. Dabei handelt es sich um Stringressourcen, die der Nutzer sehen kann, wenn
er eine Liste von Berechtigungen
(android:label)
oder Details zu einer einzelnen Berechtigung
(android:description) aufruft.
Das Label ist kurz: Es besteht aus einigen Wörtern, die die wichtigste Funktion beschreiben, die durch die Berechtigung geschützt wird. Die Beschreibung besteht aus ein paar Sätzen, in denen beschrieben wird, was der Inhaber mit der Berechtigung tun kann. Unsere Konvention ist eine Beschreibung mit zwei Sätzen, wobei der erste Satz die Berechtigung beschreibt und der zweite Satz den Nutzer vor den möglichen Problemen warnt, die auftreten können, wenn einer App die Berechtigung gewährt wird.
Hier ein Beispiel für ein Label und eine Beschreibung für die
CALL_PHONE
Berechtigung:
<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>
Berechtigungsgruppe erstellen
Wie im vorherigen Abschnitt gezeigt, können Sie mit dem
android:permissionGroup Attribut dem System helfen,
Berechtigungen für den Nutzer zu beschreiben. In den meisten Fällen legen Sie dies auf eine Standard
Systemgruppe fest (aufgelistet in
android.Manifest.permission_group).
Sie können aber auch mit
<permission-group> eine eigene Gruppe definieren.
Das <permission-group> Element definiert ein Label für eine Reihe
von Berechtigungen – sowohl für die im Manifest mit
<permission>
Elementen deklarierten als auch für die an anderer Stelle deklarierten Berechtigungen. Dies wirkt sich nur darauf aus, wie die Berechtigungen gruppiert werden, wenn sie dem Nutzer präsentiert werden. Das
<permission-group>
Element gibt nicht die Berechtigungen an, die zur Gruppe gehören, aber
gibt der Gruppe einen Namen.
Sie können eine Berechtigung in der Gruppe platzieren, indem Sie den Gruppennamen dem
<permission>
Attribut des
permissionGroup
Elements zuweisen.
Das
<permission-tree>
Element deklariert einen Namespace für eine Gruppe von Berechtigungen, die im
Code definiert sind.
Empfehlungen für benutzerdefinierte Berechtigungen
Sie können benutzerdefinierte Berechtigungen für Ihre Apps definieren und benutzerdefinierte Berechtigungen
von anderen Apps anfordern, indem Sie <uses-permission> Elemente definieren.
Sie sollten jedoch sorgfältig prüfen, ob dies erforderlich ist.
- Wenn Sie eine Suite von Apps entwickeln, die Funktionen für einander freigeben, sollten Sie die Apps so gestalten, dass jede Berechtigung nur einmal definiert wird. Dies ist erforderlich, wenn die Apps nicht alle mit demselben Zertifikat signiert sind. Auch wenn die Apps alle mit demselben Zertifikat signiert sind, ist es eine Best Practice, jede Berechtigung nur einmal zu definieren.
- Wenn die Funktion nur für Apps verfügbar ist, die mit derselben Signatur wie die bereitstellende App signiert sind, können Sie möglicherweise benutzerdefinierte Berechtigungen vermeiden, indem Sie Signaturprüfungen verwenden. Wenn eine Ihrer Apps eine Anfrage an eine andere Ihrer Apps sendet, kann die zweite App prüfen, ob beide Apps mit demselben Zertifikat signiert sind, bevor sie die Anfrage erfüllt.
Wenn eine benutzerdefinierte Berechtigung erforderlich ist, sollten Sie prüfen, ob nur Anwendungen darauf zugreifen müssen, die vom selben Entwickler wie die Anwendung signiert wurden, die die Berechtigungsprüfung durchführt. Dies ist beispielsweise der Fall, wenn Sie eine sichere Interprozesskommunikation zwischen zwei Anwendungen desselben Entwicklers implementieren. In diesem Fall empfehlen wir die Verwendung von Signaturberechtigungen. Signaturberechtigungen sind für den Nutzer transparent und vermeiden Berechtigungen, die vom Nutzer bestätigt werden müssen, was für Nutzer verwirrend sein kann.
Weitere Informationen:
<uses-permission>- API-Referenz für das Manifest-Tag, mit dem die erforderlichen Systemberechtigungen Ihrer App deklariert werden.
Weitere Themen, die Sie interessieren könnten:
- Android-Sicherheitsübersicht
- Eine detaillierte Erläuterung des Sicherheitsmodells der Android-Plattform.