Guide étape par étape de la signature de code Android et de la signature de code avec Codemagic

Connectez-vous avec plus de 3 000 devs d’applications mobiles sur Slack Rejoignez la communauté Codemagic

Créer des applications est une passion partagée par les développeurs de logiciels du monde entier. Mais les frais administratifs liés à la gestion de la signature du code sont lugubres. Comment faire pour que tout se passe bien du premier coup ? Lewis Cianci se penche sur la question.

Laissez-moi vous dire ceci d’emblée.

La signature de code est si ennuyeuse qu’elle me fait mal aux dents. C’est un concept qui existe pour une bonne raison. Je veux dire, vous voulez que les gens soient sûrs que votre logiciel vient bien de vous, non ? ! Et pourtant, c’est quelque chose que tant de développeurs ont du mal à faire au quotidien. C’est comme faire ses impôts après une année complète de travail et avoir tant de formulaires à remplir. Youpi.

La signature de code est comme faire vos impôts après une année complète de travail et avoir tant de formulaires à remplir. Codemagic a un grand guide étape par étape pour simplifier votre vie
Cliquez pour tweeter

Défilez vers le bas si vous voulez juste voir le guide étape par étape sur la signature de code Android et que vous n’êtes pas intéressé par la raison pour laquelle nous faisons cela😉

Pourquoi nous signons le code

Nous signons nos paquets afin que les personnes qui téléchargent notre paquet à partir du Play Store sachent réellement que c’est nous. Nous le faisons en signant notre paquet avec une clé que nous générons. Lorsque nous téléchargeons notre paquet signé sur Google Play, il se souvient de la clé qui a été utilisée pour télécharger le paquet initial et s’assure que les paquets suivants sont signés avec la même clé.

Pour atteindre cet objectif, la signature des paquets Android tire en fait avantage d’un outil qui provient du cadre de développement Java appelé keytool. Keytool a été autour pour probablement aussi longtemps que le JDK lui-même, donc il est assez vieux. Cela se prête probablement à certaines des raisons pour lesquelles la signature d’un APK ou d’un AAB (android app bundle) est aussi confuse qu’elle l’est.

Pourquoi le Play Store ne peut-il pas simplement gérer la signature du code pour nous ?

Nous serions tentés de demander un nirvana où nous pourrions simplement donner tous nos bundles d’applications non signés au Play Store et simplement les faire travailler et simplement les signer pour nous. Mais la logique de cette idée s’effondre rapidement. Si vous écriviez un livre, demanderiez-vous à quelqu’un d’autre de le signer ? Non. Vous le signeriez parce que vous êtes l’auteur.

De nos jours, la signature du code est beaucoup plus facile que ce qu’elle était auparavant. Tant que nous signons toujours nos paquets avec la même clé (la « clé de téléchargement »), Google Play va en fait générer et gérer nos clés de signature de code pour nous.

Si vous êtes particulièrement entreprenant, vous pouvez tenter de tout lire et comprendre ici, mais je développe pour Android depuis la majeure partie de trois ans maintenant et je suis triste de dire que même moi, je ne le comprends pas complètement. Tout ce que je sais, c’est que quand ça casse, c’est une énorme douleur à réparer.

Prenons le temps de comprendre non seulement comment coder le signe mais aussi pourquoi nous codons le signe. Lorsque nous comprenons la nécessité de ce processus, il sera plus facile à compléter.

Qu’est-ce que nous avons besoin pour la signature de code ?

La version courte est ici. Pour la signature de code, nous devons :

  • créer le fichier du kit de développement Java (JDK) ;
  • signer notre bundle d’application ou APK avec notre clé privée ;
  • modifier le build.gradle ;
  • envoyer le paquet au distributeur (Google Play).

À la fin de cet article, vous trouverez également comment faire fonctionner la signature de code avec Codemagic.

Version un peu plus longue avec un guide étape par étape sur ce dont nous avons besoin pour la signature de code Android et comment le faire.

Guide étape par étape pour la signature de code Android

STEP 1 : Le kit de développement Java (JDK)

Si vous développez pour Android, vous avez probablement déjà installé ces éléments.

Nous devons créer un fichier Java Key Store (JKS) qui contient nos informations de signature. En générant un JKS pour notre application, nous créons en fait une clé privée sur notre ordinateur. Cette clé privée est protégée par un mot de passe que nous définissons.

À partir d’une invite de commande, nous pouvons taper ce qui suit pour obtenir un JKS.

keytool -genkey -v -keystore %DESKTOP%/key.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias DEVELOPERNAME

Nous disons à keytool de générer un Java Key Store et de le mettre sur notre bureau. Cette clé sera valide pendant 10 000 jours ou environ 27 ans, ce qui nous permettra de pousser des mises à jour pendant toute la durée de vie de notre application. Nous devons également définir un alias. J’en fais simplement mon nom de développeur ou quelque chose dont je me souviendrai.

keytool demandera diverses informations en cours de route. Il est important de les spécifier correctement car nous définissons essentiellement les détails de notre clé privée.

On vous demandera :

  • Mot de passe du keystore – vous en aurez besoin pour déverrouiller à nouveau ce keystore à l’avenir. Si vous perdez ce mot de passe, il est à peu près impossible de le récupérer.
  • Rentrer le mot de passe du keystore
  • Détails personnels sur ce qu’il faut mettre dans le certificat personnel

On nous demandera de remplir quelques détails nous concernant. Ce sont les détails qui sont associés à notre clé privée, donc ils devraient être quelque peu pertinents. C’est à vous de décider ce que vous mettez dans ces champs, mais en règle générale, je ne ferais pas trop de folies.

C’est la sortie de keytool.

C:\code\signingtest\android\app>keytool -genkey -v -keystore key.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias androidappsEnter keystore password:Re-enter new password:What is your first and last name?: Codemagic Article DudeWhat is the name of your organizational unit?: Fantastic Apps And Where To Find ThemWhat is the name of your organization?: GreatappsWhat is the name of your City or Locality?: EstoniaWhat is the name of your State or Province?: TartuWhat is the two-letter country code for this unit?: EEIs CN=Codemagic Article Dude, OU=Fantastic Apps And Where To Find Them, O=Greatapps, L=Estonia, ST=Tartu, C=ES correct?:

Prêtez attention ! Si vous ne faites que spammer Enter à travers ce processus, la création va juste tourner en boucle encore et encore pendant que vous répondez « non » à la dernière question.

En faisant cela, nous avons créé un JKS et nous y avons mis notre propre clé privée générée. Parce que nous l’avons générée et que nous avons défini le mot de passe, nous pouvons être sûrs que toute personne qui a ce fichier JKS est soit nous, soit spécifiquement autorisée à l’utiliser.

Si quelqu’un a votre JKS et les bonnes informations d’identification, il peut signer des paquets en tant que vous ou votre entreprise. Gardez-le en sécurité, ne le mettez pas sur le contrôle de source.

Maintenant nous avons notre Java Key Store, donc nous sommes à mi-chemin ! Réjouissez-vous en conséquence.

Etape 2 : Signer notre bundle d’application ou APK avec notre clé privée

Maintenant, nous voulons signer notre bundle d’application avec ce JKS que nous venons de faire. Il est possible de signer manuellement le code de notre APK ou de notre release build à chaque fois, mais en réalité, nous ferions mieux de le configurer de sorte que lorsque nous exécutons flutter build apk --release, il signe simplement automatiquement notre paquet avec la bonne clé de téléchargement. La documentation de Flutter parle de la façon de mettre à jour les fichiers Gradle ici, mais nous allons le faire lentement et l’expliquer en cours de route.

Pour commencer, ouvrons notre fichier flutter_app/android/app/build.gradle. Sur environ la ligne 49, nous pouvons voir ceci:

buildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so flutter run --release works. signingConfig signingConfigs.debug }}

La principale chose qui se passe ici est que nos builds sont signés avec le keystore debug, donc notre release build fonctionne toujours. Nous voulons changer cela pour que nos versions soient signées avec notre propre keystore. De cette façon, elles peuvent être téléchargées sur le Google Play store.

La première chose que nous faisons est de créer un key.properties dans notre répertoire d’applications. Nous le créons dans flutter_app/android/key.properties.

key.properties comprendra tous les détails dont nous avons besoin pour signer avec succès notre paquet.

storePassword=The JKS store passwordkeyPassword=The key passwordkeyAlias=The alias for your keystoreFile=Where to look for your keystore file

Une note rapide sur le contrôle de la source

Vous devriez réfléchir avant de vérifier ce code dans le contrôle de la source. Si des acteurs malveillants obtenaient l’accès au keystore et à ces informations d’identification, et s’ils avaient le contrôle de vos comptes, ils pourraient potentiellement pousser une nouvelle mise à jour de votre application avec des logiciels malveillants ou d’autres mauvaises choses. La plupart des solutions CI/CD vous permettent de fournir ces détails en tant que « secrets », mais la mise en œuvre diffère par plateforme.

STEP 3 : Récapitulation & Modification du build.gradle

Nous avons créé un fichier keystore, et spécifié un alias, ainsi qu’un mot de passe pour protéger leur keystore. Si nous utilisons la signature des applications Google Play (ce que vous utilisez par défaut), la clé que nous avons générée sert de clé de téléchargement. Le premier paquet que nous téléchargeons via la console Google Play sera signé avec cette clé. Cela prouve à Google que nous sommes bien ceux que nous prétendons être.

C’est logique ? Cool, faisons-le signer dans le cadre de notre processus de construction de Flutter.

Modifiez le build.gradle

Ouvrez flutter_app/android/app/build.gradle. À la ligne 31 environ, vous devriez voir un texte comme celui-ci :

android { compileSdkVersion 29` lintOptions { disable 'InvalidPackage' }...

Nous voulons indiquer à Gradle où trouver le magasin de clés. Nous le faisons en mettant ces détails sur environ la ligne 28, au-dessus de l’instruction android {.

def keystoreProperties = new Properties()def keystorePropertiesFile = rootProject.file('key.properties')if (keystorePropertiesFile.exists()) { keystoreProperties.load(new FileInputStream(keystorePropertiesFile))}

Décomposons ce qui précède…

Nous définissons une variable keystoreProperties. Ensuite, nous vérifions si key.properties existe relativement à la racine de notre projet android (pas le projet Flutter).

Lorsque notre build s’exécute, il charge key.properties. key.properties identifie l’emplacement du keystore, plus les informations d’identification nécessaires pour déverrouiller le Java Key Store afin de signer le paquet. Avec tous les détails requis en main, Gradle signe maintenant le paquet d’applications ou APK dans le cadre de notre build de libération.

Vérifions simplement que tous nos fichiers sont au bon endroit.

Notre agencement de projet android
Notre agencement de projet android

Notre build.gradle modifié est dans flutter_app/android/app/build.gradle.

Notre fichier key.jks est dans flutter_app/android/app/key.jks.

Notre fichier key.properties est dans flutter_app/android/key.properties.

Une fois que nous sommes sûrs de ce qui précède, nous devrions être en mesure d’exécuter flutter build apk --release maintenant et la signature devrait fonctionner correctement.

STEP 4 : L’envoyer à Google Play Store

Nous pouvons maintenant télécharger notre APK ou notre paquet d’applications sur le Play Store. Lorsque nous le faisons avec notre paquet signé, et avec Google Play Signing activé (ce qui est le cas par défaut), Google reconnaîtra la clé que nous avons utilisée pour signer le paquet et la retiendra comme notre clé de téléchargement. Google signera ensuite notre APK ou notre paquet d’applications avec sa propre clé. Il est important que toutes les mises à jour ultérieures que nous fournissons pour cette application soient signées avec cette même clé. Google Play reconnaît cette clé comme notre clé de téléchargement et nous ne pouvons pas publier de mises à jour sans elle.

Je ne comprends rien de ce qui précède et j’apprécierais une illustration incroyablement visuelle de ce qui se passe exactement.

Can do ! C’est ce qui se passe.

  1. Nous générons un moyen super secret de nous identifier, presque comme si nous nous fabriquions un passeport.
  2. Parce que toute personne possédant ce « passeport » sera capable de s’identifier positivement comme nous (ie : se faire passer pour nous sans trop de résistance), nous le verrouillons derrière un mot de passe dans notre coffre-fort (le JKS, ou Java Key Store).
  3. Nous créons le paquet d’applications ou APK, puis nous signons le paquet avec la même signature que celle utilisée sur le passeport. Pour accéder à ce passeport, nous devons déverrouiller le coffre-fort dans lequel il se trouve (en fournissant le mot de passe et l’alias au processus de construction Gradle).
  4. Nous envoyons le paquet au distributeur (Google Play). Le distributeur, voyant le paquet pour la première fois, prend note de notre signature que nous avons utilisée sur ce paquet et en prend une copie.
  5. Lorsque nous envoyons des paquets à notre distributeur (Google Play) dans le futur, nous signons ces paquets avec les mêmes détails que nous avons utilisés initialement. Notre distributeur, se souvenant des détails que nous avons utilisés initialement pour télécharger le paquet, accepte ou rejette le paquet. Si elles correspondent (si la clé de téléchargement est la même que celle que nous avons utilisée initialement), alors le paquet est accepté et distribué. Sinon, il n’est pas accepté.
  6. Notre distributeur, sachant que le paquet initial et les futurs paquets potentiels proviennent certainement de nous, distribue le paquet.

Faire fonctionner la signature de code avec Codemagic

Nous voulons finalement signer cela dans le cadre de notre flux de travail CI/CD, mais en même temps, nous ne voulons pas enregistrer notre keystore et notre fichier de propriétés dans le contrôle de source. Au lieu de cela, nous voulons que notre fournisseur CI/CD construise le paquet et le signe plus tard dans le processus de construction avec un keystore que nous fournissons.

Se configurer avec Git

Si nous avons une application Flutter totalement nouvelle, alors nous pouvons passer au dossier et taper git init pour commencer à utiliser le contrôle de la source avec l’application.

Par défaut, nous allons juste vérifier joyeusement notre keystore et notre fichier de propriétés keystore, ce qui est une mauvaise idée du point de vue de la sécurité.

Vous devriez obtenir cela dès le début

Si vous vérifiez accidentellement vos propriétés keystore et votre fichier keystore et que vous poussez ces changements, les gens pourront arracher ces fichiers à tout moment dans le futur en regardant votre historique Git. Vous pouvez supprimer manuellement les fichiers de Git à l’avenir, ou vous pouvez réinitialiser votre dépôt sans ces fichiers, mais il est préférable de simplement ne pas les vérifier en premier lieu.

Nous voulons ajouter ces lignes à la fin de notre fichier .gitignore:

# Don't check in the keystore files or equivalent*.jkskey*.properties

Aucun KeyStore Java (JKS) ou propriétés pour la signature de code ne sera vérifié dans le contrôle de la source. Comment lovely.

Making build.gradle not sign when running on CI/CD

Pendant que votre projet se construit, le keystore et les paramètres ne sont pas disponibles. Nous voulons que le build produise quand même un release build même s’il n’est pas signé.

C’est la partie de mon build.gradle qui permet cela:

signingConfigs { file(rootProject.file('key.properties')).with { propFile -> if (propFile.canRead()) { release { keyAlias keystoreProperties keyPassword keystoreProperties storeFile file(keystoreProperties) storePassword keystoreProperties } } else { print('not signed') } }}buildTypes { release { file(rootProject.file('key.properties')).with { propFile -> if (propFile.canRead()) { // because we can read the keystore // we are building locally // so sign locally // otherwise build an unsigned apk for later signing by the CI/CD provider signingConfig signingConfigs.release } } applicationVariants.all { variant -> variant.outputs.all { output -> output.outputFileName = "app-release.apk" } } // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. // signingConfig signingConfigs.release }}

Paramétrage de Codemagic pour signer nos builds

Dans votre processus de build, trouvez la section de signature du code Android (c’est dans la section Publish). Cela ressemble à ceci:Android code signing

Maintenant, nous téléchargeons notre keystore et définissons notre mot de passe, notre alias de clé et notre mot de passe de clé (qui sont les mêmes que ceux que nous avons définis initialement dans notre fichier keystore.properties).

Détails remplis
Détails remplis

Puis nous appuyons sur « Save ». Lorsque Codmagic exécutera notre processus de construction, il produira automatiquement un APK ou un App Bundle signé pour nous.

Et c’est à peu près tout ! Avec cet APK ou App Bundle signé, vous pouvez déployer votre application sur le Play Store.

Vous pouvez consulter mon repo Git pour un exemple ici (évidemment, sans le keystore ou les propriétés).

C’est tout.

Si vous êtes toujours perdu, n’hésitez pas à me le faire savoir à @azimuthapps et j’essaierai d’aider. Cela peut être frustrant d’y arriver, mais une fois que vous l’avez fait, cela devrait fonctionner dans un avenir prévisible.

Lewis Cianci est un développeur de logiciels à Brisbane, en Australie. Son premier ordinateur avait un lecteur de bandes. Il développe des logiciels depuis au moins dix ans, et a utilisé pas mal de frameworks de développement mobile (comme Ionic et Xamarin Forms) en son temps. Mais après s’être converti à Flutter, il ne reviendra jamais en arrière. Vous pouvez le joindre sur son blog, lire d’autres choses non Flutter sur Medium, ou peut-être l’apercevoir dans votre café le plus proche et le plus chic avec lui et sa chère femme.

Plus d’articles par Lewis :

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.