Conversion d’un certificat protégé par mot de passe (pfx) en certificat non protégé (snk)

Oct 4, 2014

Au travail je suis en train de mettre en place du build automatisé pour des projets SharePoint (full trust) sur visual studio online. (Attendez-vous à voir plusieurs articles à ce sujet au fur et à mesure que je rencontre et résous des erreurs)

Qui dit développement SharePoint dit assemblies signés par un certificat. Lorsque l’on initialise le projet on a deux options :

  • Certificat est protégé par mot de passe : (extension pfx) c’était au début du tooling SharePoint, ou bien si vous avez monté la structure de solution (visual studio) vous-même avec plusieurs assemblies.
  • Certificat non protégé : (extension snk) option par défaut du tooling depuis quelques années

Dans mon cas le certificat était protégé par mot de passe, cependant le problème c’est qu’il faut taper ce mot de passe lorsque l’on veut compiler pour la première fois les sources sur une nouvelle machine. Ce n’est vraiment pas pratique lorsque l’on fait du build automatisé (pas d’humain pour taper un mot de passe lors de la compilation). Ce qui nous donne des messages d’erreur de ce genre.

Cannot import the following key file: cert.pfx. The key file may be password protected. To correct this, try to import the certificate again or manually install the certificate to the Strong Name CSP with the following key container name: VS_KEY_XXXXXXXXXXXXXXX

C’est d’autant moins pratique lorsque l’on essaie de configurer ça avec les hosted build machines. Ces machines sont des machines pré configurées par Microsoft pour éviter d’avoir à monter sa propre machine de build. (on ne peut donc pas les administrer).

Le framework msbuild ne fournit pas de manière simple de rentrer le mot de passe et l’outil en ligne de commande sn.exe (sert à importer les certificats dans le store de la machine) prompte lui aussi pour le mot de passe. En fait c’est logique : un mot de passe doit être mémorisé mais écrit nulle part. (principe de sécurité de base).

Il me restait donc à supprimer le mot de passe du certificat, seulement l’interface visual studio ne permet pas d’effectuer cela. Il n’y a qu’à générer un nouveau certificat dans ce cas ? Surtout pas ! Cela va changer la public key du nom d’assembly et potentiellement poser des problèmes pour tous les éléments enregistrés en base de données après la mise à jour ! (je pense notamment aux event receivers).

La solution ? Convertir le certificat grâce à un bout de code (exécuté dans une app console) trouvé sur pastebin https://pastebin.com/dpMxqsK4

X509Certificate2 cert = new X509Certificate2(@“KEY.pfx”, “pfxPassword”, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);

RSACryptoServiceProvider provider = (RSACryptoServiceProvider) cert.PrivateKey;

byte[] array = provider.ExportCspBlob(!provider.PublicOnly);

using (FileStream fs = new FileStream(“FileName.snk”, FileMode.Create,     FileAccess.Write))

{

fs.Write(array, 0, array.Length);

}

En espérant que cela vous fasse gagner du temps dans la mise en place de vos builds automatisés sur visual studio online.

PS : idéalement votre entreprise devrait acheter un certificat intermédiaire public et monter une PKI. A partir de cette PKI vous devriez générer vos certificats protégés par mot de passe. Ces certificats devraient être importés une fois (via GPO si possible) sur les machines des développeurs et les machines de build. Cela permettrait de :

  • garder la clef privée protégée même en cas de vol des sources
  • ne pas avoir à donner le mot de passe aux développeurs ou à le mettre dans un script
  • permettre à vos clients de s’assurer que l’assembly qu’ils reçoivent a bien été publié par vous et non par un attaquant
  • mettre en place du build automatisé (sur vos machines uniquement pas celles hébergées par VS online)

(voir authenticode https://msdn.microsoft.com/fr-fr/library/ms172240.aspx )


Edité la dernière fois le 27 May 2021 par Vincent Biret


Tags: