Best Practices für Android-Apps
Die in diesem Artikel beschriebenen Best Practices verbessern die Kompatibilität zwischen Citrix Endpoint Management™ und mobilen Apps für Android-Geräte.
MDX App SDK und Wrapping
Wenn Ihre App das MDX App SDK verwendet, müssen Sie die passende MDX Toolkit-Version für das Wrapping verwenden. Eine Versionsinkompatibilität zwischen diesen beiden Komponenten kann zu Fehlfunktionen führen.
- Um eine solche Inkompatibilität zu vermeiden, wrappen Sie die App mit einem App-Typ von Premium oder General. Dadurch können Sie eine vorab gewrappte App bereitstellen. Infolgedessen muss Ihr Kunde die App nicht wrappen, wodurch die Verwendung eines inkompatiblen MDX Toolkits vermieden wird. Details zum Wrapping von Apps finden Sie unter Wrapping von Android-Mobil-Apps.
Den Haupt-Thread nicht blockieren
Sie sollten keinen blockierenden Code verwenden, wenn Sie auf dem Haupt-Thread ausgeführt werden. Dies ist eine Google-Richtlinie, aber mit Citrix Endpoint Management ist sie noch wichtiger. Einige Aktionen können in einer verwalteten App länger dauern oder sogar die weitere Thread-Ausführung blockieren.
Blockierender Code umfasst, ist aber nicht beschränkt auf, Folgendes:
- Datei- oder Datenbankoperationen
- Netzwerkoperationen
Zur Klarstellung: Alle App-Lebenszyklusmethoden, wie z. B. onCreate, werden auf dem Haupt-Thread ausgeführt.
Google bietet eine StrictMode-API, die helfen kann, blockierenden Code zu erkennen. Details finden Sie in diesem Blogbeitrag: https://android-developers.blogspot.com/2010/12/new-gingerbread-api-strictmode.html.
-
Robusten Code schreiben
Insbesondere sollten Sie Rückgabewerte überprüfen oder Ausnahmen von Framework-APIs abfangen. Obwohl dies eine gängige Best Practice in der Programmierung ist, ist sie für verwaltete Apps besonders wichtig.
Verschiedene APIs, von denen Sie erwarten würden, dass sie immer funktionieren, schlagen fehl, wenn Citrix Endpoint Management-Richtlinien die zugrunde liegende Funktionalität blockieren. Beispiele hierfür wären alle zuvor beschriebenen Funktionen:
- Netzwerk-APIs schlagen fehl, als ob kein Netzwerk verfügbar wäre.
- Sensor-APIs, wie GPS und Kamera, geben null zurück oder lösen eine Ausnahme aus.
- Intents, die an eine nicht verwaltete App gerichtet sind, schlagen fehl.
- Der Datei- und Datenbankzugriff kann fehlschlagen, wenn er vom Haupt-Thread aus verwendet wird. Details finden Sie in den Abschnitten „Sicherstellen der Datenverschlüsselungskompatibilität“ und „Benutzer-Entropie für die Verschlüsselung“ weiter unten in diesem Artikel.
Wenn ein Fehler auftritt, sollte Ihre App das Problem elegant behandeln, anstatt abzustürzen.
Hooking-Einschränkungen
MDX injiziert Funktionalität in eine binäre Android-App, indem es den DEX-Code in der APK modifiziert. Es gibt mehrere Einschränkungen:
- Citrix Endpoint Management verwaltet möglicherweise keine veralteten Framework-Klassen aus den Android SDK-Versionen vor 4.0. Stellen Sie sicher, dass Sie diese veralteten Klassen vermeiden.
- Die meisten Funktionen werden in die Java/Android-Framework-APIs injiziert. Nativer (C/C++) Code wird im Allgemeinen nicht verwaltet. Eine Ausnahme ist, dass selbst bei nativem Code die Dateiverschlüsselung weiterhin erfolgt.
- Nativer Code, der JNI verwendet, um auf Java-Funktionalität zuzugreifen, darf nur Code in der Benutzer-App ansprechen. Mit anderen Worten, verwenden Sie JNI nicht, um Java- oder Android-Framework-Methoden direkt aufzurufen. Verwenden Sie stattdessen das Proxy-Entwurfsmuster, um die gewünschte Framework-Klasse in einer eigenen Java-Klasse zu „wrappen“. Rufen Sie dann Ihre Klasse aus dem nativen Code auf.
Sicherstellen der Datenverschlüsselungskompatibilität
- Eines der Hauptmerkmale von MDX ist, dass alle persistenten Daten transparent verschlüsselt werden. Sie müssen Ihre App nicht ändern, um diese Funktionalität zu erhalten, und können sie tatsächlich nicht direkt vermeiden. Der Administrator hat die Möglichkeit, die Verschlüsselung selektiv oder vollständig zu deaktivieren, die App jedoch nicht.
- Dies ist einer der schwerwiegenderen Aspekte von MDX und erfordert ein Verständnis der folgenden Punkte:
-
Die Dateiverschlüsselung ist für alle Java- und nativen Codes vorhanden, die in verwalteten Prozessen ausgeführt werden.
-
Einige Framework-APIs, wie z. B. Mediaplayer und Druckunterstützung, werden tatsächlich in separaten Betriebssystemprozessen ausgeführt. Wenn Sie eine solche API verwenden, können Probleme auftreten.
- Beispiel: Ihre App speichert eine Datei auf der Festplatte (verschlüsselt) und übergibt dann eine Referenz auf die Datei an eine Medien-API. Die Medien-API versucht, die Datei zu lesen, versteht aber den verschlüsselten Inhalt nicht. Sie schlägt fehl oder lässt die App sogar abstürzen.
- Beispiel: Sie erstellen ein Dateihandle (das eine verschlüsselte Datei startet) und übergeben es der Kamera-API. Der Kameraprozess schreibt unverschlüsselte Daten direkt in die verschlüsselte Datei. Wenn Ihre App versucht, diese Daten zu lesen, werden die Daten entschlüsselt, was zu Datenmüll führt.
-
Eine Methode zur Handhabung separater Prozesse besteht darin, eine Datei zu entschlüsseln, bevor sie an die entsprechende API übergeben wird. Oder wenn die API Daten schreibt, würden Sie sie zuerst schreiben lassen und sie dann verschlüsseln, wenn die API fertig ist. Es sind einige Schritte erforderlich:
-
- Legen Sie einen Bereich fest, der unverschlüsselt bleiben soll. Sie müssen dies für Ihren Kunden dokumentieren, da ein Citrix Endpoint Management-Administrator eine Richtlinie zur Verschlüsselungsausnahme erstellen muss.
-
- Zum Entschlüsseln kopieren Sie die Datei einfach vom normalen (verschlüsselten) Speicherort an den entschlüsselten Speicherort. Beachten Sie, dass Sie eine Byte-Kopie und keine Dateiverschiebung durchführen müssen.
-
- Zum Verschlüsseln kehren Sie die Richtung um. Kopieren Sie von unverschlüsselten zu verschlüsselten Speicherorten.
-
- Löschen Sie die unverschlüsselte Datei, wenn sie nicht mehr benötigt wird.
-
Speicherzuordnung wird für verschlüsselte Dateien nicht unterstützt. Wenn Sie eine API aufrufen, die Speicherzuordnung durchführt, schlägt dies fehl. Sie sollten den Fehler behandeln. Vermeiden Sie nach Möglichkeit die direkte und indirekte Verwendung von Speicherzuordnung. Ein bemerkenswerter Fall indirekter Verwendung ist die Drittanbieterbibliothek SqlCipher.
-
Wenn Sie die Speicherzuordnung nicht vermeiden können, muss der Administrator eine Richtlinie zur Verschlüsselungsausnahme festlegen, die die relevanten Dateien ausschließt. Sie müssen diese Richtlinie für Ihren Kunden dokumentieren.
-
Verschlüsselung verursacht einen messbaren Overhead. Stellen Sie sicher, dass Sie die Datei-I/O optimieren, um eine Leistungsverschlechterung zu vermeiden. Wenn Sie beispielsweise dieselben Informationen wiederholt lesen und schreiben, sollten Sie möglicherweise einen App-Level-Cache implementieren.
-
Datenbanken sind nur Dateien und werden daher ebenfalls verschlüsselt. Auch hier kann die Leistung ein Problem darstellen. Die Standard-Datenbank-Cache-Größe beträgt 2000 Seiten oder 8 Megabyte. Wenn Ihre Datenbank groß ist, sollten Sie diese Größe möglicherweise erhöhen.
- Der SQLite WAL-Modus wird aufgrund der Einschränkung der Speicherzuordnung nicht unterstützt.
-
Benutzer-Entropie für die Verschlüsselung
Eine Citrix Endpoint Management-Option für die Verschlüsselung erfordert, dass der Endbenutzer eine PIN eingibt, bevor der Verschlüsselungsschlüssel generiert werden kann. Diese Option wird als Benutzer-Entropie bezeichnet. Sie kann ein bestimmtes Problem für Apps verursachen.
Insbesondere kann kein Datei- oder Datenbankzugriff durchgeführt werden, bevor der Benutzer eine PIN eingibt. Wenn eine solche I/O-Operation an einem Ort vorhanden ist, der ausgeführt wird, bevor die PIN-Benutzeroberfläche angezeigt werden kann, schlägt sie immer fehl. Es gibt einige Implikationen:
- Halten Sie Datei- und Datenbankoperationen vom Haupt-Thread fern. Zum Beispiel schlägt ein Versuch, eine Datei aus der onCreate()-Methode des App-Objekts zu lesen, immer fehl.
- Hintergrundoperationen, wie Dienste oder Content-Provider, können ausgeführt werden, auch wenn keine App-Aktivität vorhanden ist. Diese Hintergrundkomponenten können die PIN-Benutzeroberfläche nicht anzeigen und daher keinen Datei- oder Datenbankzugriff durchführen. Beachten Sie, dass, sobald eine Aktivität in der App ausgeführt wird, die Hintergrundoperationen I/O-Operationen durchführen dürfen.
Es gibt mehrere Fehlermechanismen, wenn der Verschlüsselungsschlüssel aufgrund der Benutzer-Entropie nicht verfügbar ist:
- Wenn der Haupt-Thread auf eine Datenbank zugreift, bevor die PIN verfügbar ist, wird die App beendet.
- Wenn ein Nicht-Haupt-Thread auf eine Datenbank zugreift, bevor die PIN verfügbar ist, wird dieser Thread blockiert, bis die PIN eingegeben wurde.
- Für den Nicht-Datenbankzugriff, der gestartet wurde, bevor die PIN verfügbar ist, schlägt der Öffnungsvorgang fehl. Auf C-Ebene wird ein EACCES-Fehler zurückgegeben. In Java wird eine Ausnahme ausgelöst.
Um sicherzustellen, dass dieses Problem in Ihrer App nicht auftritt, testen Sie mit aktivierter Benutzer-Entropie. Die Citrix Endpoint Management-Client-Eigenschaft „Geheimnisse mit Passcode verschlüsseln“ (Encrypt secrets using Passcode) fügt Benutzer-Entropie hinzu. Sie konfigurieren diese Client-Eigenschaft, die standardmäßig deaktiviert ist, in der Citrix Endpoint Management-Konsole unter Konfigurieren > Einstellungen > Mehr > Client-Eigenschaften.
Netzwerk und Micro-VPN
- Für Administratoren stehen mehrere Richtlinienoptionen von Citrix Endpoint Management für die Netzwerkverwaltung zur Verfügung. Die Richtlinie für den Netzwerkzugriff verhindert, erlaubt oder leitet die Netzwerkaktivität von Apps um.
- >Wichtig:
- > >Die Version 18.12.0 des MDX Toolkits enthielt neue Richtlinien, die ältere Richtlinien kombinierten oder ersetzten. Die Richtlinie für den Netzwerkzugriff kombiniert Netzwerkzugriff, bevorzugten VPN-Modus und die Umschaltung des VPN-Modus. Die Richtlinie für die Ausschlussliste ersetzt die Ausschlussliste für Split-Tunnel. Die Richtlinie für die erforderliche Micro-VPN-Sitzung ersetzt die Richtlinie für die erforderliche Online-Sitzung. Weitere Informationen finden Sie unter [Neuerungen in früheren Releases](/de-de/mdx-toolkit/about-mdx-toolkit/whats-new.html#whats-new-in-earlier-releases).
Die Optionen sind wie folgt:
- **Vorherige Einstellungen verwenden**: Standardmäßig werden die Werte verwendet, die Sie in den früheren Richtlinien festgelegt hatten. Wenn Sie diese Option ändern, sollten Sie nicht zu **Vorherige Einstellungen verwenden** zurückkehren. Beachten Sie auch, dass Änderungen an den neuen Richtlinien erst wirksam werden, wenn der Benutzer die App auf Version 18.12.0 oder höher aktualisiert.
- **Blockiert**: Von Ihrer App verwendete Netzwerk-APIs schlagen fehl. Gemäß der vorherigen Richtlinie sollten Sie solche Fehler ordnungsgemäß behandeln.
- **Uneingeschränkt**: Alle Netzwerkaufrufe erfolgen direkt und werden nicht getunnelt.
-
Getunnelt – Vollständiges VPN: Der gesamte Datenverkehr der verwalteten App wird über Citrix Gateway getunnelt.
-
Einschränkung: Citrix Endpoint Management unterstützt keinen Socket-Server. Wenn ein Socket-Server innerhalb der umschlossenen App ausgeführt wird, wird der Netzwerkverkehr zum Socket-Server nicht über Citrix Gateway getunnelt.
Unterstützung für mobile App-Entwicklungsframeworks
Einige App-Frameworks weisen Kompatibilitätsprobleme mit Citrix Endpoint Management auf:
- Mit PhoneGap wird der Standortdienst nicht blockiert.
-
SQLCipher funktioniert nicht mit Verschlüsselung, da es Speicherzuordnung verwendet. Eine Lösung besteht darin, SQLCipher nicht zu verwenden. Eine zweite Lösung besteht darin, die Datenbankdatei mithilfe einer Verschlüsselungsausschlussrichtlinie von der Verschlüsselung auszuschließen. Ein Citrix Endpoint Management-Administrator muss die Richtlinie in der Citrix Endpoint Management-Konsole konfigurieren.
-
Tipps zur Fehlerbehebung
Beachten Sie beim Debuggen einer umschlossenen App die folgenden Tipps.
- Stellen Sie fest, ob das Problem in einer nicht-umschlossenen Version der App auftritt. Wenn das Problem im nicht-umschlossenen Zustand auftritt, verwenden Sie normale Debugging-Techniken.
- Versuchen Sie, verschiedene Citrix Endpoint Management-Richtlinien zu deaktivieren.
- Dies kann helfen, Inkompatibilitäten zu lokalisieren. Das Deaktivieren einer Richtlinie bedeutet, dass MDX die entsprechende Einschränkung nicht mehr durchsetzt, sodass Sie diese Funktionen testen können, als ob die App nicht umschlossen wäre.
- Wenn das Deaktivieren einer Richtlinie das Problem behebt, liegt das Problem möglicherweise darin, dass die App keine Fehler in den zugehörigen APIs prüft.
- Wenn eine unveränderte, aber neu signierte App nicht ausgeführt wird:
-
- Entpacken Sie den Inhalt der APK mit JAR:
[[CODE_BLOCK_0]]
-
Löschen Sie den META-INF-Ordner:
[[CODE_BLOCK_1]]
-
Packen Sie den Inhalt mit JAR in eine neue APK:
[[CODE_BLOCK_2]]
-
Signieren Sie die neue APK mit JARSIGNER:
[[CODE_BLOCK_3]]
-
Wenn die App immer noch nicht ausgeführt wird, können Sie die App nicht mit einem anderen Signaturzertifikat als dem ursprünglich verwendeten APK umschließen.
-
- Wenn eine dekompilierte oder rekompilierte .apk nicht ausgeführt wird:
-
Dekomprimieren und rekompilieren Sie mit APKTOOL:
[[CODE_BLOCK_4]]
[[CODE_BLOCK_5]]
-
Signieren Sie die APK mit JARSIGNER wie oben beschrieben.
-
Wenn die App immer noch nicht ausgeführt wird, ist dies ein Fehler in einem Drittanbieter-APKTOOL.
-
- Wenn das App-Wrapping nicht funktioniert:
- Versuchen Sie, das APKTOOL-Framework zu entfernen und neu zu umschließen.
- Mac/Linux: rm -rf ~/Library/apktool/framework
- Windows: del /q /s C:\Users\{username}\apktool\framework
- Vergleichen Sie, welches APKTOOL vom Wrapper verwendet wird, mit dem, das Sie im vorherigen Schritt erfolgreich zum Dekompilieren und Rekompilieren verwendet haben.
- Wenn es dieselbe APKTOOL-Version ist, liegt ein Fehler im Wrapper vor.
- Wenn es eine andere APKTOOL-Version ist, könnte ein Fehler im in das MDX Toolkit-Dienstprogramm integrierten APKTOOL vorliegen.
- Entpacken Sie den Inhalt von ManagedAppUtility.jar.
- Überschreiben Sie mit dem Inhalt von APKTOOL.jar, das Sie im vorherigen Schritt erfolgreich zum Umschließen der App verwendet haben.
- Packen Sie den Inhalt in eine neue ManagedAppUtility.jar.
- Umschließen Sie die App, um den Fehler im eingebetteten APKTOOL zu bestätigen.
- Versuchen Sie, das APKTOOL-Framework zu entfernen und neu zu umschließen.
- Führen Sie die umschlossene App aus und erfassen Sie Protokollinformationen.
-
Verwenden Sie grep, um zu untersuchen, was in der App geschieht.
Um den Aktivitäten der App zu folgen: grep “MDX-Activity”
Um die MDX-Sperrung der App zu verfolgen: grep “MDX-Locked”
Um beide Protokolle zusammen anzuzeigen: egrep “MDX-Act MDX-Loc” -
Wenn ein Fehler vom Typ “Anwendung reagiert nicht” auftritt, rufen Sie die ANR-Traces mit ADB ab.
-
- Wenn ein Problem bei der Interaktion mit mehreren Apps auftritt, z. B. bei der Verwendung von “Öffnen in”:
- Überprüfen Sie, ob die Verschlüsselungsrichtlinien und Sicherheitseinstellungen zwischen den Apps identisch sind.
- Versuchen Sie eine andere App. Es könnte ein Fehler in einer der getesteten Apps vorliegen.
- Erfassen Sie Protokolle von allen beteiligten Apps. Beachten Sie, dass Secure Hub Protokolle bündeln und Protokolle von einzelnen Apps per E-Mail versenden kann. Wischen Sie auf dem Bildschirm “Meine Apps” nach rechts zum Bildschirm “Support”. Klicken Sie dann unten auf dem Bildschirm auf die Schaltfläche “Hilfe benötigt”.
Zusätzlich zu den oben genannten Tools können auch die folgenden hilfreich sein:
-
AAPT zum Ausgeben von Informationen über die App.
aapt dump badging {some.apk}
-
DUMPSYS-Befehl auf dem Gerät.
adb shell dumpsys 2>&1 | tee {dumpsys.out}
-
DEX2JAR zum Rekompilieren von Klassen in Pseudo-Java.
dex2jar {some.apk}
Klassen aus Dual-Dex-umschlossenen Apps konvertieren:
apktool d {some.apk} -o {some.dir}
dex2jar {some.dir}/assets/secondary-1.dex
-
JD-GUI zum Anzeigen von Pseudo-Java-Code.
-
BAKSMALI zum Dekompilieren von App-Klassen aus Dual-Dex-umschlossenen Apps.
-
Dekomprimieren Sie die umschlossene APK:
apktool d {some.apk} -o {some.dir}
-
Dekomprimieren Sie die Klassen der App, die nicht durch den obigen Aufruf dekompiliert werden:
baksmali {some.dir}/assets/secondary-1.dex -o {some.dir}/smali
-
In diesem Artikel
- MDX App SDK und Wrapping
- Den Haupt-Thread nicht blockieren
- Robusten Code schreiben
- Hooking-Einschränkungen
- Sicherstellen der Datenverschlüsselungskompatibilität
- Benutzer-Entropie für die Verschlüsselung
- Netzwerk und Micro-VPN
- Unterstützung für mobile App-Entwicklungsframeworks
- Tipps zur Fehlerbehebung