Geräte-IDs

In Android 10 wurden die Berechtigungen für Geräte-IDs geändert. Alle Geräte-IDs sind jetzt durch die Berechtigung READ_PRIVILEGED_PHONE_STATE geschützt. Vor Android 10 waren gleichbleibende Geräte-IDs (IMEI/MEID, IMSI, SIM und Build-Seriennummer) durch die Laufzeitberechtigung READ_PHONE_STATE geschützt. Die Berechtigung READ_PRIVILEGED_PHONE_STATE wird nur Apps gewährt, die mit dem Plattformschlüssel signiert sind, und privilegierten System-Apps.

Weitere Informationen zu den neuen Berechtigungsanforderungen finden Sie auf den Javadoc-Seiten für TelephonyManager.java und Build.java.

Diese Änderung betrifft die folgenden APIs:

  • TelephonyManager#getDeviceId
  • TelephonyManager#getImei
  • TelephonyManager#getMeid
  • TelephonyManager#getSimSerialNumber
  • TelephonyManager#getSubscriberId
  • Build#getSerial

Zugriff für Mobilfunkanbieter-Apps ohne die Berechtigung READ_PRIVILEGED_PHONE_STATE

Vorinstallierte Carrier-Apps, die nicht für die Berechtigung READ_PRIVILEGED_PHONE_STATE infrage kommen, können eine der Optionen in der Tabelle unten implementieren.

Option Beschreibung Beschränkungen
UICC-Mobilfunkanbieterberechtigungen Die Android-Plattform lädt auf der UICC gespeicherte Zertifikate und erteilt Apps, die mit diesen Zertifikaten signiert sind, die Berechtigung, spezielle Methoden aufzurufen. Legacy-Mobilfunkanbieter haben eine große, etablierte SIM-Population, die nicht einfach aktualisiert werden kann. Außerdem können Mobilfunkanbieter, die keine Berechtigung zum Erstellen neuer SIMs haben (z. B. MVNOs, die SIMs von MNOs ausgeben lassen), keine Zertifikate auf den SIMs hinzufügen oder aktualisieren.
OEM-Zulassungsliste Originalgerätehersteller können OP_READ_DEVICE_IDENTIFIER verwenden, um Geräte-IDs für zugelassene Mobilfunkanbieter-Apps bereitzustellen. Diese Lösung ist nicht für alle Mobilfunkanbieter skalierbar.
TAC (Type Allocation Code) Verwenden Sie die Methode getTypeAllocationCode, die in Android 10 eingeführt wurde, um den TAC verfügbar zu machen, der die Hersteller- und Modellinformationen zurückgibt. Die Informationen im TAC reichen nicht aus, um ein bestimmtes Gerät zu identifizieren.
MSISDN Mobilfunkanbieter können die Telefonnummer (MSISDN), die unter TelephonyManager mit der Berechtigungsgruppe PHONE verfügbar ist, verwenden, um die IMEI in ihren Backend-Systemen nachzuschlagen. Dies erfordert erhebliche Investitionen für Mobilfunkanbieter. Mobilfunkanbieter, die ihre Netzwerkschlüssel mit IMSI zuordnen, benötigen erhebliche technische Ressourcen, um auf MSISDN umzustellen.

Alle Carrier-Apps können auf Geräte-IDs zugreifen, indem sie die Datei CarrierConfig.xml mit dem Hash des Signaturzertifikats der Carrier-App aktualisieren. Wenn die Carrier-App eine Methode zum Lesen privilegierter Informationen aufruft, sucht die Plattform in der Datei CarrierConfig.xml nach einer Übereinstimmung mit dem Hash des Signaturzertifikats der App (SHA-1- oder SHA-256-Signatur des Zertifikats). Wenn eine Übereinstimmung gefunden wird, werden die angeforderten Informationen zurückgegeben. Wenn keine Übereinstimmung gefunden wird, wird eine Sicherheitsausnahme zurückgegeben.

So implementieren Sie diese Lösung:

  1. Aktualisiere CarrierConfig.xml mit dem Hash des Signaturzertifikats der Carrier-App und reiche einen Patch ein.
  2. Fordern Sie OEMs auf, ihren Build mit QPR1+ (empfohlen) ODER diesen erforderlichen Plattform-Patches und dem Patch mit der aktualisierten CarrierConfig.xml-Datei aus Schritt 1 oben zu aktualisieren.

Implementierung

Aktualisieren Sie die Zulassungsliste für Berechtigungen mit privilegiertem Zugriff, um die Berechtigung READ_PRIVILEGED_PHONE_STATE den privilegierten Apps zu gewähren, die Zugriff auf Geräte-IDs benötigen.

Weitere Informationen zum Aufnehmen in die Zulassungsliste finden Sie unter Zulassungsliste für Berechtigungen mit erhöhten Berechtigungen.

Damit eine App die betroffenen APIs aufrufen kann, muss sie eine der folgenden Anforderungen erfüllen:

  • Wenn die App eine vorab geladene privilegierte App ist, muss die Berechtigung READ_PRIVILEGED_PHONE_STATE in „AndroidManifest.xml“ deklariert werden. Die App muss diese privilegierte Berechtigung auch auf die Zulassungsliste setzen.
  • Apps, die über Google Play bereitgestellt werden, benötigen Berechtigungen für Mobilfunkanbieter. Weitere Informationen zum Gewähren von Berechtigungen für Mobilfunkanbieter finden Sie auf der Seite UICC Carrier Privileges.
  • Eine App des Geräte- oder Profilinhabers, der die Berechtigung READ_PHONE_STATE gewährt wurde.

Eine App, die eine dieser Anforderungen nicht erfüllt, hat folgendes Verhalten:

  • Wenn die App auf eine Version vor Android Q ausgerichtet ist und die Berechtigung READ_PHONE_STATE nicht erteilt wurde, wird SecurityException ausgelöst. Das ist das aktuelle Verhalten vor Android Q, da diese Berechtigung zum Aufrufen dieser APIs erforderlich ist.
  • Wenn die App auf Versionen vor Q ausgerichtet ist und die Berechtigung READ_PHONE_STATE hat, erhält sie für alle TelephonyManager-APIs einen Nullwert und Build.UNKNOWN für die Methode Build#getSerial.
  • Wenn die App auf Android 10 oder höher ausgerichtet ist und eine der neuen Anforderungen nicht erfüllt, wird eine SecurityException ausgelöst.

Validierung und Tests

Die Compatibility Test Suite (CTS) enthält Tests, mit denen das erwartete Zugriffsverhalten auf Geräte-IDs für Apps mit Betreiberberechtigungen, Geräte- und Profilinhabern sowie für Apps, die keinen Zugriff auf Geräte-IDs haben sollen, überprüft wird.

Die folgenden CTS-Tests sind spezifisch für dieses Feature.

cts-tradefed run cts -m CtsCarrierApiTestCases -t
    android.carrierapi.cts.CarrierApiTest

cts-tradefed run cts -m CtsTelephonyTestCases -t
    android.telephony.cts.TelephonyManagerTest

cts-tradefed run cts -m CtsTelephony3TestCases

cts-tradefed run cts -m CtsPermissionTestCases -t
    android.permission.cts.TelephonyManagerPermissionTest

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.DeviceOwnerTest#testDeviceOwnerCanGetDeviceIdentifiers

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.ManagedProfileTest#testProfileOwnerCanGetDeviceIdentifiers

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.ManagedProfileTest#testProfileOwnerCannotGetDeviceIdentifiersWithoutPermission

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.DeviceOwnerTest#testDeviceOwnerCannotGetDeviceIdentifiersWithoutPermission

Häufig gestellte Fragen

Wie viele Apps können in CarrierConfig.xml für ein bestimmtes (MCC, MNC) auf die Zulassungsliste gesetzt werden?

Die Anzahl der im Array enthaltenen Zertifikathashes ist nicht begrenzt.

Welche CarrierConfig-Parameter in CarrierConfig.xml muss ich verwenden, damit eine App auf die Zulassungsliste gesetzt wird?

Verwenden Sie das folgende Konfigurationselement der obersten Ebene innerhalb des spezifischen CarrierConfig.xml aus den AOSP-Optionen, die Sie konfigurieren:

<string-array name="carrier_certificate_string_array" num="2">
    <item value="BF02262E5EF59FDD53E57059082F1A7914F284B"/>
    <item value="9F3868A3E1DD19A5311D511A60CF94D975A344B"/>
</string-array>

Gibt es eine CarrierConfig-Basisvorlage, die ich verwenden kann?

Verwenden Sie die folgende Vorlage. Dies sollte dem relevanten Asset hinzugefügt werden.

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<carrier_config>
    <string-array name="carrier_certificate_string_array"
num="1">
        <item value="CERTIFICATE_HASH_HERE"/>
    </string-array>
</carrier_config>

Muss sich die SIM-Karte des Mobilfunkanbieters im Gerät befinden, um auf Geräte-IDs zugreifen zu können?

Die verwendete CarrierConfig.xml hängt von der aktuell eingelegten SIM-Karte ab. Wenn also die App von Mobilfunkanbieter X versucht, auf Berechtigungen zuzugreifen, während die SIM-Karte von Mobilfunkanbieter Y eingelegt ist, findet das Gerät keine Übereinstimmung für den Hash und gibt eine Sicherheitsausnahme zurück.

Auf Geräten mit mehreren SIM-Karten hat Mobilfunkanbieter 1 nur Zugriffsberechtigungen für SIM-Karte 1 und umgekehrt.

Wie konvertieren Mobilfunkanbieter das Signaturzertifikat einer App in einen Hash?

So wandeln Sie Signaturzertifikate in einen Hash um, bevor Sie sie CarrierConfig.xml hinzufügen:

  1. Konvertieren Sie die Signatur des Signaturzertifikats mit toByteArray in ein Byte-Array.
  2. Verwenden Sie MessageDigest, um das Byte-Array in einen Hash vom Typ „byte[]“ zu konvertieren.
  3. Wandeln Sie den Hash vom Byte-Array in einen Hex-String um. Ein Beispiel finden Sie unter IccUtils.java.

    List<String> certHashes = new ArrayList<>();
    PackageInfo pInfo; // Carrier app PackageInfo
    MessageDigest md =
    MessageDigest.getInstance("SHA-256");
    for (Signature signature : pInfo.signatures) {
        certHashes.add(bytesToHexString(md.digest(signature.toByteArray()));
    }
  4. Wenn certHashes ein Array der Größe 2 mit dem Wert 12345 und 54321 ist, fügen Sie der Carrier-Konfigurationsdatei Folgendes hinzu.

    <string-array name="carrier_certificate_string_array" num="2">
        <item value="12345"/>
        <item value="54321"/>
    </string-array>