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:
- Aktualisiere
CarrierConfig.xmlmit dem Hash des Signaturzertifikats der Carrier-App und reiche einen Patch ein. - 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:
- Wenn die App eine vorinstallierte privilegierte App ist, muss die Berechtigung
READ_PRIVILEGED_PHONE_STATEin der AndroidManifest.xml deklariert werden. Die App muss diese privilegierte Berechtigung auch auf die Zulassungsliste setzen. - Über Google Play bereitgestellte Apps benötigen Mobilfunkanbieter-Berechtigungen. Weitere Informationen zum Gewähren von Betreiberberechtigungen auf der Seite „UICC Carrier Privileges“
- Eine Geräte- oder Profilinhaber-App, der die Berechtigung
READ_PHONE_STATEgewährt wurde.
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_STATEnicht erteilt wurde, wirdSecurityExceptionausgelö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_STATEerteilt wurde, erhält sie für alle TelephonyManager-APIs einen Nullwert undBuild.UNKNOWNfür die MethodeBuild#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.CarrierApiTestcts-tradefed run cts -m CtsTelephonyTestCases -t android.telephony.cts.TelephonyManagerTestcts-tradefed run cts -m CtsTelephony3TestCasescts-tradefed run cts -m CtsPermissionTestCases -t android.permission.cts.TelephonyManagerPermissionTestcts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.DeviceOwnerTest#testDeviceOwnerCanGetDeviceIdentifierscts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.ManagedProfileTest#testProfileOwnerCanGetDeviceIdentifierscts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.ManagedProfileTest#testProfileOwnerCannotGetDeviceIdentifiersWithoutPermissioncts-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:
- Konvertieren Sie die Signatur des Signaturzertifikats mit
toByteArrayin ein Byte-Array. - Verwenden Sie
MessageDigest, um das Byte-Array in einen Hash vom Typ byte[] zu konvertieren. -
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())); } Wenn
certHashesein Array der Größe2mit dem Wert12345und54321ist, 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>