Geräte-IDs

In Android 10 wurden die Berechtigungen für Geräte-IDs geändert, sodass alle Geräte-IDs jetzt durch die Berechtigung READ_PRIVILEGED_PHONE_STATE geschützt sind. 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 gewährt Apps, die mit diesen Zertifikaten signiert sind, die Berechtigung, spezielle Methoden aufzurufen. Ältere Mobilfunkanbieter haben eine große, etablierte SIM-Population, die sich nicht einfach aktualisieren lässt. Außerdem können Mobilfunkanbieter, die keine Berechtigung zum Erstellen neuer SIMs haben (z. B. MVNOs, deren SIMs von MNOs ausgestellt werden), keine Zertifikate auf den SIMs hinzufügen oder aktualisieren.
Zulassungsliste für OEMs Originalgerätehersteller können OP_READ_DEVICE_IDENTIFIER verwenden, um Geräte-IDs für Apps von Mobilfunkanbietern auf der Zulassungsliste bereitzustellen. Diese Lösung ist nicht für alle Mobilfunkanbieter skalierbar.
Type Allocation Code (TAC) Verwende die in Android 10 eingeführte Methode getTypeAllocationCode, um den TAC offenzulegen, der die Hersteller- und Modellinformationen zurückgibt. Die Informationen in der 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 seitens der Mobilfunkanbieter. Mobilfunkanbieter, die ihre Netzwerkschlüssel mithilfe von IMSI zuordnen, benötigen erhebliche technische Ressourcen, um auf MSISDN umzustellen.

Alle Mobilfunkanbieter-Apps können auf Geräte-IDs zugreifen, indem die Datei CarrierConfig.xml mit dem Hash des Signaturzertifikats der Mobilfunkanbieter-App aktualisiert wird. Wenn die Mobilfunkanbieter-App eine Methode zum Lesen vertraulicher 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 oder höher (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 für die 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 Rechten.

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

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

  • Wenn die App auf Versionen 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 erteilt wurde, 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 ausgegeben.

Validierung und Tests

Die Compatibility Test Suite (CTS) enthält Tests, mit denen das erwartete Verhalten beim Zugriff auf Geräte-IDs für Apps mit Betreiberberechtigungen, Geräte- und Profilinhaber 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 einen bestimmten (MCC, MNC) auf die Zulassungsliste gesetzt werden?

Die Anzahl der Zertifikat-Hashes im Array 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 in der 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. Diese 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 richtet sich nach der aktuell eingelegten SIM-Karte. 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 wandeln Mobilfunkanbieter das Signaturzertifikat einer App in einen Hash um?

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. Konvertieren Sie den Hash von byte[] in ein Hex-String-Format. 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 Konfigurationsdatei des Mobilfunkanbieters Folgendes hinzu.

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