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:
- Aktualisiere
CarrierConfig.xmlmit dem Hash des Signaturzertifikats der Carrier-App und reiche einen Patch ein. - 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_STATEin „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_STATEgewä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_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_STATEhat, 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 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.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 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:
- 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. -
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())); } Wenn
certHashesein Array der Größe2mit dem Wert12345und54321ist, 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>