Comment signer des applications pour macOS Catalina 10.15

image

[Remarque trad.: traduisant le post qui a provoqué une large discussion sur Habré, je me suis intéressé aux nouvelles règles pour les développeurs de logiciels introduites par Apple. Cet article parle de l'expérience personnelle de la maîtrise des règles avec l'un des développeurs de jeux.]

Présentation


Dans la nouvelle version de macOS, Apple a fait certaines exigences pour les applications qui étaient auparavant des recommandations: fichiers exécutables 64 bits, signature et notarisation. Les applications qui ne répondent pas à ces exigences ne seront plus lancées.

Cela est fait afin de protéger le travail des utilisateurs et d'empêcher la propagation de programmes malveillants, mais en même temps, cela rend la vie très difficile, en particulier pour les personnes pour lesquelles le Mac n'est pas la principale plate-forme de développement, mais qui souhaitent néanmoins démarrer ou continuer à prendre en charge Mac .

Cela est particulièrement vrai pour les développeurs de jeux qui publient des jeux Mac sur Steam. Jusqu'à des changements récents, les jeux lancés à partir de Steam n'avaient pas besoin de signer et de certifier, mais maintenant ils devaient obéir aux mêmes règles que tout le monde.

Je viens de finir de comprendre comment mettre en œuvre ces exigences pour mon jeu Airships: Conquer the Skies . Les dirigeables fonctionnent en Java, et nécessitent donc une JVM, mais en général, tout le reste sera applicable à la plupart des développeurs.

Voici ce que j'ai appris sur la signature et la légalisation d'une application Mac qui n'a pas été compilée directement par Xcode. Veuillez noter que les informations proviennent de mes propres recherches et peuvent ne pas être exactes à 100%. Les questions et corrections sont les bienvenues.

Contexte


Cet article traite de la signature et de la notarisation. L'obtention du fichier exécutable 64 bits du programme est la tâche de votre compilateur ou de votre environnement de développement.

Sous macOS, les applications sont généralement regroupées dans des dossiers groupés contenant l'exécutable, ainsi que des ressources et des métadonnées supplémentaires. Signer un bundle signifie créer une somme de contrôle cryptographique du contenu du bundle puis créer une signature cryptographique avec un certificat qu'Apple délivre au développeur. Une signature est une déclaration que vous garantissez personnellement le bon comportement de l'application. Si le contenu de l'ensemble change, la somme de contrôle change et la signature cesse de leur correspondre, avertissant le système d'exploitation que des modifications non autorisées ont été apportées à l'ensemble.

La signature d'applications existe depuis de nombreuses années. Un peu plus tard, des demandes sont également devenues nécessaires pour la notarisation. La notarisation signifie que vous soumettez une application Apple signée et que l'entreprise effectue des vérifications supplémentaires et enregistre l'application. Si la notarisation réussit, vous «collez» la notarisation à votre application, afin que les machines hors ligne sans accès à Internet puissent également s'assurer que l'application a été notariée.

C'est une sorte de métaphore pour travailler avec des documents papier. Le développeur rassemble dans un bundle toutes les pièces qui composent l'application. Il crée ensuite une liste de tous les éléments du bundle (checksum) et signe cette liste (avec une signature numérique), qu'il colle au bundle. Il passe ensuite le paquet signé au notaire M. Yablokov, qui vérifie si tout est en ordre avec le paquet, puis l'enregistre. Il remet au développeur un reçu que l'agrafeuse attache au paquet. Autrement dit, si le développeur a déclaré que l'application est sûre, et M. Yablokov dit également qu'elle est sûre, alors il est très probable qu'elle le soit. Et si une mauvaise personne essaie de changer son contenu, alors la liste des éléments du bundle cessera de lui correspondre, et l'utilisateur saura qu'il n'est pas nécessaire de l'utiliser.

Prérequis


Ce qui est nécessaire pour signer et authentifier la demande:

  • Un ordinateur Mac suffisamment récent pour exécuter Xcode 11 dessus, c'est-à-dire suffisamment nouveau pour exécuter macOS 10.14.3. Si vous n'avez pas encore installé Xcode, 25 Go d'espace libre sont nécessaires pour l'installation.
  • Si vous n'êtes pas encore un développeur Apple officiel, un identifiant Apple et environ 110 $ sont requis pour devenir membre.

Authentification à deux facteurs


Si vous n'en avez pas encore, activez l'authentification à deux facteurs pour votre identifiant Apple. Cela peut être fait à partir de n'importe quel appareil i ou d'un Mac. Sur un Mac, accédez au panneau de configuration iCloud des paramètres des Préférences Système. En haut, il devrait y avoir un panneau suggérant d'activer 2FA.

Achat d'adhésion


Connectez-vous à https://developer.apple.com/ à l' aide de votre identifiant Apple et accédez à l'onglet Adhésion. Achetez ou mettez à niveau votre adhésion au programme pour développeurs Apple si nécessaire. Veuillez noter que le traitement d'un achat prend du temps sur les systèmes internes d'Apple, donc si vous ne parvenez pas à générer de certificats (voir ci-dessous), buvez une tasse de thé pendant un moment et calmez-vous.

Identifiant d'application


Vous devrez peut-être enregistrer l'ID de l'ensemble d'applications dans le backend du développeur. L'ID du bundle se trouve dans YourApp.app/Contents/Info.plist. (Vous pouvez ouvrir des ensembles d'applications en cliquant dessus avec le bouton droit de la souris et en sélectionnant «Afficher le contenu du package».) L'identifiant doit être com.votre nom de société.nom d'application, par exemple, mon jeu Airships a com.zarkonnen.airships.

Pour enregistrer un ID, connectez-vous à https://developer.apple.com/ , sélectionnez «Certificats, ID et profils» dans le volet gauche, puis sélectionnez «Identifiants» sur la page suivante. Ensuite, vous pouvez cliquer sur le bouton "+" pour ajouter l'identifiant de l'application.

Mot de passe d'application


Pour vous connecter à partir de la ligne de commande, vous aurez besoin du mot de passe de l'application, alors allez sur https://appleid.apple.com/account/manage et générez-le.

Xcode et outils


Installez Xcode via l'App Store de Mac App. Installez ensuite également les outils de ligne de commande Xcode depuis https://developer.apple.com/download/more . Vous avez besoin des outils de ligne de commande pour Xcode 11 ou la version de Xcode que vous utilisez.

Attestation


Lancez Xcode, allez dans Préférences, ouvrez l'onglet Comptes. Si nécessaire, ajoutez votre identifiant Apple à la liste des comptes. Cliquez ensuite sur le bouton "Gérer les certificats ..." dans le coin inférieur droit. Les certificats dont vous disposez pour signer les applications s'affichent. Vous avez besoin d'un certificat «Developer ID Application»; s'il ne figure pas dans la liste, créez-le. Cliquez sur "Terminé" puis sur "Télécharger" dans la fenêtre Préférences: Comptes pour télécharger les certificats localement.

Préparation de la demande


Pour que l'application fonctionne correctement sur le nouveau système, le fichier exécutable et les bibliothèques doivent être 64 bits.

De plus, Mac OS effectue une opération appelée «translocation»: pour des raisons de sécurité, il déplace le paquet d'applications en cours d'exécution vers un emplacement aléatoire. Dans le cas de ma candidature, cela s'est manifesté par le fait qu'il n'a pas pu trouver les fichiers de données situés à côté du bundle d'applications. Vous pouvez obtenir l'emplacement d'origine du bundle de l'application, mais j'ai résolu le problème en plaçant simplement tout dans le bundle.

Autorisations (droits)


Ce sont des autorisations spéciales ajoutées par le développeur avec la signature de code, permettant aux applications signées d'effectuer certaines actions. Si vous compilez l'application à l'aide de Xcode, elle fera tout d'elle-même; sinon, vous devrez créer un fichier plist contenant tous les droits dont vous avez besoin. Les fichiers Plist peuvent être créés à l'aide de Xcode, et à https://developer.apple.com/documentation/bundleresources/entitlements il y a une liste de droits.

Pour créer un nouveau fichier plist à l'aide de Xcode, sélectionnez «Nouveau fichier» puis cliquez sur «Liste des propriétés» dans la liste qui apparaît. Ajoutez les éléments avec les droits dont vous avez besoin au dictionnaire racine; ils ont les significations booléennes: OUI.


Dans le cas de mon jeu, car il est écrit en Java, j'avais besoin des autorisations suivantes pour que la machine virtuelle Java fonctionne: com.apple.security.cs.allow-jit, com.apple.security.cs.allow-unsigned-executable-memory, com. apple.security.cs.disable-executable-page-protection, com.apple.security.cs.disable-library-validation, com.apple.security.cs.allow-dyld-variables-d'environnement. Pour l'utilisateur, ils semblent intimidants, donc si vous n'en avez pas besoin, ne les ajoutez pas.

Plus loin dans l'article, nous supposerons que vous avez placé vos droits dans un fichier appelé droit.plist.

Signature


Il s'agit du processus de création d'une signature numérique informant: celui qui a accès au certificat de signature promet que ce bundle d'application particulier est fiable et non malveillant. Tout changement dans le bundle de l'application (sauf pour joindre une confirmation de notarisation, voir ci-dessus) après sa signature invalide la signature et nécessite une nouvelle signature du bundle.

Cela signifie également que votre application ne doit rien changer dans le contenu du bundle d'application, par exemple, n'y mettez pas de cache.

Chaque fichier exécutable et bibliothèque dynamique du bundle d'application sont signés séparément. Dans certains cas, les bibliothèques peuvent déjà être signées. Autrement dit, il est plus poli et plus calme de signer un bundle en signant chaque élément tour à tour, puis de signer l'intégralité du bundle. Si un élément a déjà une signature, il restera à sa place.

Un moyen grossier mais efficace consiste à forcer la signature profonde, c'est-à-dire que votre signature sera appliquée à tous les éléments du bundle d'application, en remplacement de toutes les signatures précédentes. C'est exactement ce que nous allons faire, car c'est plus simple et parce que les signatures précédentes peuvent être invalides ou pas assez fortes.

Vous aurez besoin de la commande effrayante suivante:

codesign -s "Developer ID Application: <YourName>" --timestamp --options runtime -f --entitlements entitlements.plist --deep YourApp.app

L'option --timestamp signifie qu'un horodatage valide, nécessaire pour une notarisation réussie, est intégré à la signature.

L'option --options runtime signifie que la signature inclut "hardened runtime", qui est également nécessaire pour une notarisation réussie.

Vous pouvez apprendre la signature de l'équipe

codesign -d -vvvv YourApp.app

Vous devez également exécuter l'application pour vous assurer qu'elle continue de fonctionner après la signature.

Si vous souhaitez signer des éléments de manière plus polie, supprimez les commandes -f et --deep de la commande, signez d'abord tous les fichiers exécutables et les bibliothèques à l'intérieur de l'application, puis l'application entière.

Notarisation


Après avoir signé l'application, vous devez la fournir aux systèmes Apple pour la notarisation afin de dire: "Écoutez, j'ai signé cette chose."

Pour ce faire, commencez par compresser l'application dans un fichier zip spécial à l'aide de la commande idem:

/usr/bin/ditto -c -k --keepParent YourApp.app YourApp.zip

Envelopper simplement l'application dans zip à l'aide du Finder ou la ligne de commande ne fonctionnera pas.

Envoyez ensuite un zip pour la notarisation:

xcrun altool --notarize-app --primary-bundle-id "<id>" -u "<appleid>" -p "<app-specific password>" --file YourApp.zip

Un exemple:

xcrun altool --notarize-app --primary-bundle-id "com.zarkonnen.airships" -u "dave@hotmail.com" -p "bwnh-pbbt-llpt-xxxx" --file Airships.zip

L'ID de l'ensemble peut être trouvé en consultant YourApp.app/Contents/Info.plist. (Vous pouvez ouvrir les ensembles d'applications en cliquant avec le bouton droit sur eux et en sélectionnant «Afficher le contenu du package».)

La notarisation peut prendre un certain temps. Cela prend généralement quelques secondes ou minutes, mais parfois cela peut prendre une heure. Versez-vous plus de thé, ou quelque chose de plus fort, choisissez par vous-même. Tôt ou tard, vous obtiendrez quelque chose comme ceci:

No errors uploading 'YourApp.zip'.
RequestUUID = 29926ae6-f551-4d54-b283-e29d6f9b9156


Nous pouvons maintenant utiliser la commande suivante pour vérifier l'état du paquet transmis:

xcrun altool --notarization-info <RequestUUID> -u -u "<appleid>" -p "<app-specific password>"

Un exemple:

xcrun altool --notarization-info 29926ae6-f551-4d54-b283-e29d6f9b9156 -u "dave@hotmail.com" -p "bwnh-pbbt-llpt-xxxx"

Quelque chose de similaire sera affiché:

           Date: 2019-10-08 06:59:58 +0000
           Hachage: 0774fb95035408bacecebd64935a611ecd27b45ad9cbf3cc1aa48fa1e0eaa649
     LogFileURL: https: //osxapps-ssl.itunes.apple.com/itunes-assets/Enigma123 / ...
         Statut: succès
    Code d'état: 0
 Message d'état: package approuvé 

Je le répète, la confirmation prend généralement environ 15 minutes, mais parfois cela prend plusieurs heures pour la même application. Ouais, comme ça.

Si l'état est un échec, consultez les erreurs répertoriées par l'URL du fichier journal. Si vous réussissez, jetez un coup d'œil de toute façon, car il peut y avoir des avertissements, et ces avertissements peuvent bien devenir des erreurs lorsque Apple resserre ses exigences.

Pièce jointe


Enfin, nous allons «attacher» la confirmation de notarisation au bundle d'applications afin que même un Mac puisse le vérifier sans connexion Internet. Pour ce faire, vous devez exécuter une commande étonnamment courte:

xcrun stapler staple "YourApp.app"

Félicitations, vous avez signé et notarié l'application Mac. Vous pouvez maintenant distribuer le bundle d'applications de n'importe quelle manière qui vous convient s'il ne change pas au cours du processus.

Java


Si vous êtes dans le même bateau que moi et que vous devez ajouter au bundle avec l'application JVM, continuez à lire.

Il existe plusieurs options pour combiner un bundle JVM avec une application Java. Je recommanderais l'AppBundler, qui est une tâche de fourmi qui fait tout le travail pour vous. Initialement, l'AppBundler pouvait être téléchargé depuis java.net, mais grâce à la négligence d'Oracle du reste de la plate-forme Java, vous devez maintenant télécharger la dernière version depuis https://github.com/TheInfiniteKind/appbundler .

Vous y trouverez les sources et la documentation, mais pas le pot, car on suppose que vous utilisez Maven. Si vous n'utilisez pas Maven, le pot peut être pris ici: https://jar-download.com/artifacts/com.panayotis/appbundler

Suivez les instructions de la documentation sur la page github pour configurer le bundle. Personnellement, j'utilise NetBeans, et pour résoudre le problème, j'ai inséré les lignes suivantes dans build.xml:

 <target name = "- post-jar">
   <taskdef name = "bundleapp" 
     classpath = "lib / appbundler-1.1.0.jar"
     classname = "com.oracle.appbundler.AppBundlerTask" />
   <bundleapp 
       jvmrequired = "1.7"
       outputdirectory = "/ home / zar / Desktop"
       name = "dirigeables"
       displayname = "Dirigeables"
       executableName = "Dirigeables"
       identifier = "com.zarkonnen.airships"
       shortversion = "1"
       version = "1"
       mainclassname = "com.zarkonnen.airships.Main"
       copyright = "2019 David Stark"
       applicationCategory = "public.app-category.games">
       <classpath dir = "dist" />
       <runtime dir = "/ home / zar / Desktop / jdk-11.0.4.jdk / Contents / Home" />
       <arch name = "x86_64" />
       <option value = "- Dapple.laf.useScreenMenuBar = true" />
       <option value = "- Dcom.apple.macos.use-file-dialog-packages = true" />
       <option value = "- Dcom.apple.macos.useScreenMenuBar = true" />
       <option value = "- Dcom.apple.mrj.application.apple.menu.about.name = Dirigeables" />
       <option value = "- Xdock: name = dirigeables" />
       <option value = "- Dcom.apple.smallTabs = true" />
       <option value = "- Dfile.encoding = UTF-8" />
       <option value = "- Xmx1024M" name = "Xmx" />
   </bundleapp>
 </target> 

Il s'agit de la tâche effectuée après la création du fichier jar. Il utilise appbundler-1.1.0.jar pour créer un ensemble d'applications avec une machine virtuelle Java intégrée.

Le JDK que j'utilise peut être téléchargé à partir de https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html . J'ai choisi la version 11 car elle a LTS (support à long terme), mais utilise les anciens termes de licence Oracle, tandis que la version 13 a un étrange nouvel ensemble de restrictions de licence.

Il existe également plus de JVM OpenJDK légalement libres, mais je n'ai pas pu les faire fonctionner avec le bundle d'application.

Remarque: JVM est «Java Virtual Machine». JRE est un «environnement d'exécution Java» qui inclut la JVM et des éléments supplémentaires, tels que le programme de mise à jour Java. JDK est un «kit de développement Java» qui se compose d'un JRE et des éléments nécessaires pour écrire des programmes Java, comme un compilateur. Avant Java 8, le JRE était disponible séparément pour les utilisateurs finaux, mais depuis lors, seul le JDK était disponible, et nous associons donc l'environnement de développement Java à un jeu sur ordinateur.

Vous devriez être en mesure de signer en profondeur et de certifier le lot résultant. La documentation AppBundler contient toute une série d'options supplémentaires, telles que l'ajout d'une icône, des associations de types de fichiers et la génération d'une machine virtuelle Java allégée pour l'application.

Lectures complémentaires



Addition


  • L'utilisateur de Reddit AMemoryOfEternity a posé une question sur les forums des développeurs Steam et il s'est avéré que même si les notifications pour les applications Steam ne sont pas du tout requises. Ils devraient être en 64 bits, mais il n'est pas clair s'il est obligatoire de les signer. Lien, nécessite un accès à Steamworks
  • Apple a temporairement assoupli les règles de la notarisation, donc pour l'instant il vous permet de notariser des applications qui n'ont pas d'exécution renforcée, ont des sous-composants, n'ont pas d'ID développeur, n'ont pas d'horodatage, etc. De telles choses seront toujours affichées dans le rapport de notarisation comme des avertissements, donc pour prendre soin de l'avenir, il vaut mieux essayer de s'en débarrasser.
  • Selon Valve, pour que l'API Steam fonctionne, vous devez accorder le droit com.apple.security.cs.allow-dyld-environment-variables: «Steam injecte l'API dylib via DYLD_INSERT_LIBRARIES, qui sont bloquées par défaut par un runtime renforcé, mais l'API dylib elle-même est signée et il doit être vérifié, il suffit donc d'ajouter l'autorisation "com.apple.security.cs.allow-dyld-environment-variables" pour pouvoir attribuer des variables d'environnement DYLD. "

Source: https://habr.com/ru/post/fr471816/


All Articles