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 mit anderen Apps teilen. Weitere Informationen zu Berechtigungen finden Sie in der Übersicht über Berechtigungen.
Hintergrund
Android ist ein Betriebssystem mit separaten Berechtigungen, in dem jede App mit einer eigenen Systemidentität (Linux-Nutzer-ID und ‑Gruppen-ID) ausgeführt wird. Teile des Systems sind auch in separate Identitäten unterteilt. Linux isoliert Apps 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 jeweiligen 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 in Android dienen dazu, App-Entwickler zu unterscheiden. So kann das System Apps den Zugriff auf Berechtigungen auf Signaturniveau 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-Ebene 31) können Sie mit dem Attribut knownCerts
für Berechtigungen auf Signaturlaufzeitebene bei der Deklaration auf die Digests bekannter Signaturzertifikate verweisen.
Sie können das Attribut knownCerts
deklarieren und das Flag knownSigner
im Attribut protectionLevel
Ihrer App für eine bestimmte Berechtigung auf Signaturniveau 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 sind.
Mit dem Flag knownSigner
können Geräte und Apps anderen Apps Signaturberechtigungen gewähren, ohne dass die Apps zum Zeitpunkt der Geräteherstellung und des Versands signiert werden 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 dem 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 nicht für andere Pakete zugänglich.
Weitere Informationen zum Sicherheitsmodell von Android finden Sie unter Android-Sicherheit – Übersicht.
Berechtigungen definieren und erzwingen
Wenn Sie Ihre eigenen Berechtigungen erzwingen möchten, müssen Sie sie zuerst in Ihrem 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, darf der Nutzer auch keine anderen Pakete mit demselben Berechtigungsnamen installieren, es sei denn, diese Pakete sind mit demselben Zertifikat wie das erste Paket signiert.
Wir empfehlen, Berechtigungen mit dem Paketnamen einer App zu kennzeichnen. Verwenden Sie dazu eine Namenskonvention im Stil einer umgekehrten Domain, gefolgt von .permission.
und dann einer Beschreibung der Funktion, die die Berechtigung repräsentiert, in UPPER_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 informiert das System darüber, wie Nutzer über Apps informiert werden, die die Berechtigung benötigen, oder welche Apps die Berechtigung haben können, wie in der verlinkten Dokumentation beschrieben.
Das Attribut android:permissionGroup
ist optional und wird nur verwendet, um dem Nutzer Berechtigungen anzuzeigen. In den meisten Fällen legen Sie hier eine Standard-Systemgruppe fest (siehe android.Manifest.permission_group
). Sie können aber auch selbst eine Gruppe definieren, wie im nächsten 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. Dies sind String-Ressourcen, 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 wenigen Wörtern, die die Hauptfunktion beschreiben, die durch die Berechtigung geschützt wird. Die Beschreibung besteht aus zwei Sätzen, in denen beschrieben wird, was der Inhaber mit der Berechtigung tun kann. In der Regel wird im ersten Satz die Berechtigung beschrieben und im zweiten Satz wird der Nutzer vor den möglichen Problemen gewarnt, die auftreten können, wenn einer App die Berechtigung erteilt wird.
Hier ist ein Beispiel für ein Label und eine Beschreibung für die Berechtigung 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>
Berechtigungsgruppe erstellen
Wie im vorherigen Abschnitt gezeigt, können Sie mit dem Attribut android:permissionGroup
dem System helfen, dem Nutzer Berechtigungen zu beschreiben. In den meisten Fällen legen Sie hier eine Standardsystemgruppe fest (siehe android.Manifest.permission_group
). Sie können aber auch eine eigene Gruppe mit <permission-group>
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. Im Element <permission-group>
werden nicht die Berechtigungen angegeben, die zur Gruppe gehören, sondern die Gruppe erhält einen Namen.
Sie können einer Gruppe eine Berechtigung zuweisen, indem Sie den Gruppennamen dem Attribut permissionGroup
des Elements <permission>
zuweisen.
Mit dem Element <permission-tree>
wird ein Namespace für eine Gruppe von Berechtigungen deklariert, 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.
Prüfen Sie jedoch sorgfältig, ob dies wirklich erforderlich ist.
- Wenn Sie eine Reihe von Apps entwickeln, die sich gegenseitig Funktionen zur Verfügung stellen, sollten Sie die Apps so gestalten, dass jede Berechtigung nur einmal definiert wird. Das ist erforderlich, wenn die Apps nicht alle mit demselben Zertifikat signiert sind. Auch wenn alle Apps 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 die Definition benutzerdefinierter Berechtigungen vermeiden, indem Sie Signaturprüfungen verwenden. Wenn eine Ihrer Apps eine Anfrage an eine andere Ihrer Apps sendet, kann die zweite App überprüfen, ob beide Apps mit demselben Zertifikat signiert sind, bevor sie der Anfrage nachkommt.
Wenn eine benutzerdefinierte Berechtigung erforderlich ist, sollten Sie überlegen, ob nur Anwendungen, die vom selben Entwickler wie die Anwendung signiert wurden, die die Berechtigungsprüfung durchführt, darauf zugreifen müssen. Das ist beispielsweise der Fall, wenn eine sichere Interprozesskommunikation zwischen zwei Anwendungen desselben Entwicklers implementiert wird. In diesem Fall empfehlen wir die Verwendung von Signaturberechtigungen. Signaturberechtigungen sind für den Nutzer transparent und es sind keine vom Nutzer bestätigten Berechtigungen erforderlich, die für Nutzer verwirrend sein können.
Weitere Informationen:
<uses-permission>
- API-Referenz für das Manifest-Tag, mit dem die erforderlichen Systemberechtigungen Ihrer App deklariert werden.
Folgendes könnte Sie auch interessieren:
- Android-Sicherheit – Übersicht
- Eine detaillierte Beschreibung des Sicherheitsmodells der Android-Plattform.