(Zuerst erschienen auf: https://www.linkedin.com/pulse/android-apps-mithilfe-von-1password-signieren-julian-finkler-erlce)
Android Entwickler wissen: Wenn man eine App in den Google Play Store hochladen möchte, muss das App Bundle bzw. das APK mit einem Schlüssel signiert sein.
Als einzelner Entwickler ist der Prozess relativ trivial:
- Man legt einen Java Key Store, kurz JKS, an
- Man legt in diesem JKS einen Schlüssel zum signieren ab.
- Man legt eine key.properties Datei an, in der die die Details, wie Schlüssel oder das Passwort des Schlüssels stehen.
- Man signiert die App damit.
Der JKS sollte nicht eingecheckt werden
Aus Sicht der Sicherheit sollten natürlich sowohl der JKS als auch die Properties-Datei nicht in ein VCS eingecheckt werden. Das bringt eine Reihe von Herausforderungen mit sich:
- Ich muss mich darum kümmern, dass der JKS an einem sicheren Ort gegen Verlust gesichert wird.
- Wenn im Team gearbeitet wird, muss jeder Entwickler bei sich den JKS sowie die Properties Datei hinterlegen.
- Wenn ein Entwickler im JKS einen neuen Schlüssel hinzufügt müssen alle anderen die Datei aktualisieren.
Das ganze kann mitunter sehr mühselig sein, weswegen ich einen alternativen, besseren Weg gesucht habe, als mit Dateien zu hantieren.
1Password zur Hilfe
1Password ist in erster Linie ein Passwort Manager. Im Laufe der Jahre sind aber, gerade für Entwickler, ziemlich praktische Funktionen dazu gekommen. Darunter ist die 1Password CLI ein sehr praktisches Werkzeug, mit dem man unter anderem Daten aus 1Password lesen kann.
So kam mir die Idee: Warum sollte man diese hochsensiblen Daten irgendwo ablegen und austauschen, wenn man es auch zentral in 1Password tun kann. Folgende Vorteile erhoffte ich mir:
- Ein Ort, an dem die Information liegt.
- Gradle liest die Informationen direkt aus 1Password, ohne dass die Dateien von Hand abgelegt werden müssen.
- Neue Schlüssel stehen automatisch allen Entwicklern zur Verfügung, wenn jemand den JKS in 1Password aktualisiert.
- Keine sensiblen Daten im Repository (Gerade in Zeiten von KI Agenten ist das relevanter denn je)
Anleitung zum Einrichten
1Password CLI
Zuerst solltest du die 1Password CLI (op) installieren. Wie das geht, erfährst du in der offiziellen Doku: https://developer.1password.com/docs/cli/get-started/
Anschließend führst du auf der Kommandozeile den Befehl op signin aus, um dich einzuloggen.
JKS anlegen
Falls du noch keinen JKS hast, kannst du ihn in Android Studio ganz einfach über Build > Generate Signed App Bundle or APK anlegen. Wichtig ist, dass du dir die Werte dieser Felder irgendwo notierst, diese übernehmen wir im nächsten Schritt in 1Password.
JKS in Android Studio anlegen
Informationen in 1Password hinterlegen
Bevor die Informationen aus 1Password geladen werden können, muss dazu natürlich ein Eintrag existieren.
Ich habe dafür zunächst einen neuen Vault (Name: AndroidDevelopment) angelegt. Anschließend legt man darin ein neues Objekt vom Typen Passwort an.
Als Name habe ich mir angewöhnt, etwas URL-sicheres zu vergeben. Benutzername und Passwort können leer bleiben. Stattdessen fügen wir folgende Felder hinzu:
- KEY_ALIAS = Text. Dort wird der Alias des Schlüssel eingegeben
- KEYSTORE_PASSWORD = Passwort. Dort wird das Passwort des JKS eingegeben
- KEY_PASSWORD = Passwort. Dort wird das Passwort des Schlüssels eingegeben
- Und als letztes wird noch die keystore.jks als Anhand hinzugefügt. (Der Dateiname wird später genau so weiterverwendet)
Signatur Informationen in 1Password anlegen
Anschließend kann der Eintrag gespeichert werden.
Gradle Script anpassen
Zum schluss muss man Gradle noch dazu bringen, die Daten mittels 1Password CLI aus 1Password zu laden.
Die Anpassungen habe ich in diesem Gist auf GitHub zusammengefasst. Das Einzige was von dir noch angepasst werden muss ist Zeile 5 (val secretsItem). Dort musst du den bei dir richtigen Pfad zum oben angelegten Eintrag in 1Password hinterlegen (op://VAULT_NAME/NAME_DES_EINTRAGS). Ansonsten kannst du das Script 1:1 verwenden.
https://gist.github.com/devtronic/8db7a0a8607eabce0afb97c55fd60819
Funktionsweise
Kernstück des Ganzen ist die runOp Funktion, welche mit der 1Password CLI kommuniziert. Darüber hinaus gibt es noch zwei Tasks:
- prepareKeystore -> Lädt den JKS aus 1Password und legt die Datei an der richtigen Stelle ab
- cleanupKeystore -> Löscht den JKS direkt nach dem Build Vorgang.
Damit die Tasks ausgeführt werden, werden noch die Hooks für assembleRelease und bundleRelease eingerichtet.
In die Variablen keystorePassword, keyAliasValue und keyPasswordValue werden die entsprechenden Werte zum signieren geladen, welche dann später in die signingConfigs übernommen werden.
App bauen
Nun bist du an dem Punkt angekommen, wo du die App bauen darfst. Beim Build Vorgang wirst du das bekannte Fenster von 1Password sehen, wo du den Zugriff auf 1Password genehmigen musst.
Zugriff auf 1Password genehmigen
Fazit
Mit ein paar Handgriffen kann man mit diesem Vorgehen sicherstellen, dass auch in größeren Teams das signieren von Android Apps einfach gestaltet werden kann. Außerdem besteht somit auch die Möglichkeit, Apps in einer CI/CD Pipeline sicher zu signieren, ohne dass der JKS eingecheckt oder über Umwege geladen werden muss.
Top comments (0)