Loupe

Resigner un package Windows Store manuellement ou dans un agent VSTS Hosted

Il est facilement possible de générer un package Windows Store / UWP (appx) depuis VisualStudio ou VSTS mais une fois celui-ci testé et validé par une recette, il est encore plus intéressant de simplement re-signer celui-ci au lieu de le recompiler à partir des sources. Ainsi il n'y a pas de risque (#OnNeSaitJamais) de régression suite à une recompilation et ce que vous allez déployer sera ce que vous avez testé. 

Dans cet article, nous verrons comment resigner un package à la main depuis un poste développeur mais aussi comment le faire depuis un agent Hosted VSTS de manière sécurisée : ni le certificat, ni son mot de passe ne seront stockés dans le code source.

TL;DR;

On utilise l'utilitaire makeappx du SDK pour décompresser l'APPX, on change le signataire du package dans le manifest et on reforme l'appx avec makeappx pour le signer avec signtool.

Dépackager l'archive

Un APPX n'est rien d'autre qu'une archive ZIP créée avec un utilitaire du SDK nommé makeappx généralement situé à cet emplacement :

"C:\Program Files (x86)\Windows Kits\8.1\bin\x64\makeappx.exe"

On va donc dans un premier temps la décompresser avec ce même utilitaire. Rien de compliqué, on utilise ici ces arguments :

  • unpack : on demande une décompression
  • /p : emplacement du package.
  • /d : dossier de destination pour le contenu dé-sarchivé.
  • /l : à indiquer pour les packages internationalisés.
  • /v : verbose pour en savoir plus.
unpack /v /l /p archive.appx /d Destination

Mettre à jour le manifest

Le manifest de l'application contient l'identité du certificat utilisé pour signer le package. Il est donc nécessaire d'aller le mettre à jour dans le noeud "Package.Identity.Publisher". Il suffit de faire un remplacement à la main avec un éditeur de texte comme vim.

Repackager l'archive

On va utiliser de nouveau makeappx pour repackager le contenu de notre dossier en un package Appx complet. Les arguments à fournir sont : 

  • pack : on demande une création de package.
  • /p : emplacement du package à créer.
  • /d : dossier source pour créer le package.
  • /nv : on demande à l'outil de ne pas refaire de validation du package pour des raisons de performance.
  • /v : verbose pour en savoir plus.
  • /h SHA256 : algorithme utilisé pour créer le tableau de mapping des blocs dans l'archive. On met la valeur par défaut ici.
pack /v /nv /h SHA256 /p Package_signed.appx -d Destination

Resigner le package

On se retrouve maintenant avec un nouveau package avec la bonne identité de signature dans le manifest et il faut le signer correctement. Cela sera effectué avec l'utilitaire du SDK signtool généralement à cet emplacement :

"C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe"

On utilise signTool avec ces arguments :

  • sign : on demande une signature.
  • /p : mot de passe du certificat.
  • /f : certificat à utiliser.
  • /a : choix automatique du certificat par signtool.
  • /v : verbose pour en savoir plus.
  • /fd SHA256 : algoritme de signature à utiliser.
 sign /a /v /fd SHA256 /f Certificat.cert /p Password Package.appx

Le faire dans un agent Hosted VSTS

La difficulté ici consiste à ne pas placer le certificat dans le code source mais de le passer en paramètre de notre release VSTS. Pour solutionner cela je propose d'être efficace en fournissant le certificat en base 64 ! Il faudra alors l'écrire dans le répertoire de travail via ce script PowerShell que je vous propose :

$base64 = $args[0];
$bytes = [System.Convert]::FromBase64String($base64);

[IO.File]::WriteAllBytes("certificate.cert",$bytes );

Il est aussi nécessaire de modifier l'identité du manifest et je vous propose de le faire aussi dans un script Powershell auquel je passe l'identité à utiliser et l'emplacement du manifest en paramètres (disponibles dans $args[0] et $args[1]) : 

$manifestfile = Get-Item -Path $args[0]
$manifestXml = New-Object -TypeName System.Xml.XmlDocument
$manifestXml.Load($manifestfile.Fullname)
$manifestXml.Package.Identity.Publisher = 
$args[1]
$manifestXml.save($manifestfile.FullName)

Le reste du processus consiste uniquement à créer des tâches de type "Command Line" avec les paramètres que nous avons déjà vus auparavant.

Outre l'automatisation, l'intérêt de le faire dans un agent Hosted est aussi de ne pas avoir à installer les outils de développements sur un PC car cet étape de signature n'est pas toujours faite par une personne technique (il me semble avoir vu Thomas le faire une fois).

Happy coding :)

Photo de profil

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus