Microsoft vient de changer le certificat utilisé pour signer ses packages NuGet. Dit comme cela, l'information paraît suffisamment obscure pour être classée dans la catégorie « sécurité d'infrastructure, quelqu'un d'autre s'en occupera ».
Ce serait pourtant une mauvaise idée.
Pas parce que tous nos projets .NET vont brutalement cesser de compiler — ce n'est absolument pas le cas — mais parce que certains environnements ayant correctement durci leur chaîne d'approvisionnement NuGet peuvent, eux, commencer à refuser les nouveaux packages Microsoft.
Le paradoxe est assez amusant : ce sont précisément les équipes ayant mis en place les contrôles de sécurité les plus stricts qui doivent vérifier leur configuration.
Microsoft a annoncé le changement le 23 septembre 2026. Je vais donc regarder ce qui change réellement, qui est concerné et ce qu'il faut vérifier.
Ce qui change exactement
Microsoft signe ses packages NuGet avec un certificat X.509.
À partir du 23 septembre 2026, un nouveau certificat devient le certificat utilisé par défaut pour les nouvelles signatures d'auteur Microsoft.
L'empreinte SHA-256 du nouveau certificat est :
9A1B131BEE0605433056A4EA3815478A8E177961A968C6C0027C1093D1FEB630
L'empreinte du certificat précédemment utilisé était :
566A31882BE208BE4422F7CFD66ED09F5D4524A5994F50CCC8B05EC0528C1353
Et c'est là qu'un premier détail a son importance : les packages déjà publiés ne sont évidemment pas resignés avec le nouveau certificat.
Un ancien package conserve donc son ancienne signature.
Autrement dit, la transition ne ressemble pas à ceci :
Ancien certificat
|
X
|
Nouveau certificat
mais plutôt à ceci :
Packages déjà publiés
|
+---- signés avec certificat A
|
+---- signés avec certificat B
|
+---- signés avec certificat C
Nouveaux packages Microsoft
|
+---- signés avec certificat D
à partir de septembre 2026
Une politique de confiance correcte doit donc être capable d'accepter plusieurs générations de certificats Microsoft simultanément.
C'est une nuance importante : remplacer l'ancienne empreinte par la nouvelle serait une erreur.
Il faut ajouter la nouvelle.
Est-ce que je suis concerné ?
C'est la première question à poser, car il ne faut surtout pas transformer cette annonce en alerte générale.
Dans la majorité des environnements .NET classiques, il n'y a rien à faire.
Microsoft indique que le changement concerne principalement deux cas. Le premier est celui où NuGet est configuré avec une politique de signataires approuvés — les fameux trustedSigners.
Le second concerne les scripts ou pipelines utilisant explicitement :
dotnet nuget verify
avec une ou plusieurs empreintes de certificats Microsoft.
Si vous n'utilisez ni l'un ni l'autre, les packages Microsoft signés avec le nouveau certificat doivent continuer à s'installer normalement.
Donc avant de modifier quoi que ce soit : regardez votre configuration.
Un petit rappel sur les signatures NuGet
Une signature de package ne sert pas simplement à indiquer que « le fichier vient de Microsoft ».
Elle permet notamment de vérifier deux choses fondamentales :
Le package contient sa signature. Le client NuGet peut ensuite décider jusqu'où il souhaite pousser la vérification.
On peut schématiser grossièrement le mécanisme ainsi :
Package .nupkg
|
v
Signature NuGet
|
+--------+--------+
| |
v v
Intégrité Certificat du
du package signataire
|
v
Politique NuGet
|
+--------+--------+
| |
accepté refusé
| |
v v
restore NU3034
Le point intéressant est donc la dernière étape.
Une organisation peut parfaitement décider :
Je n'accepte pas simplement un package parce que sa signature cryptographique est valide. Je veux aussi vérifier que son signataire appartient à une liste explicitement approuvée.
C'est précisément le rôle de trustedSigners.
signatureValidationMode=require
NuGet permet de renforcer la validation avec une configuration de ce genre :
<configuration>
<config>
<add key="signatureValidationMode" value="require" />
</config>
<trustedSigners>
...
</trustedSigners>
</configuration>
Avec :
signatureValidationMode="require"
les packages doivent correspondre aux règles définies dans trustedSigners.
On peut approuver un auteur ou un repository.
Pour Microsoft, une politique basée sur l'auteur peut par exemple ressembler à ceci :
<trustedSigners>
<author name="Microsoft">
<certificate
fingerprint="3F9001EA83C560D712C24CF213C3D312CB3BFF51EE89435D3430BD06B5D0EECE"
hashAlgorithm="SHA256"
allowUntrustedRoot="false" />
<certificate
fingerprint="AA12DA22A49BCE7D5C1AE64CC1F3D892F150DA76140F210ABD2CBFFCA2C18A27"
hashAlgorithm="SHA256"
allowUntrustedRoot="false" />
<certificate
fingerprint="566A31882BE208BE4422F7CFD66ED09F5D4524A5994F50CCC8B05EC0528C1353"
hashAlgorithm="SHA256"
allowUntrustedRoot="false" />
<certificate
fingerprint="9A1B131BEE0605433056A4EA3815478A8E177961A968C6C0027C1093D1FEB630"
hashAlgorithm="SHA256"
allowUntrustedRoot="false" />
</author>
</trustedSigners>
La dernière ligne est donc celle correspondant au nouveau certificat.
Mais observez bien que Microsoft conserve également les trois empreintes précédentes.
Ce n'est pas un détail d'implémentation : c'est indispensable si l'on veut continuer à restaurer d'anciens packages Microsoft.
Ce qu'il ne faut pas faire : remplacer l'ancienne empreinte
Imaginons une politique simplifiée :
<author name="Microsoft">
<certificate
fingerprint="566A31882BE208BE4422F7CFD66ED09F5D4524A5994F50CCC8B05EC0528C1353"
hashAlgorithm="SHA256"
allowUntrustedRoot="false" />
</author>
On pourrait être tenté de remplacer cette empreinte par la nouvelle.
Ce serait faux. On obtiendrait :
Ancien package Microsoft
|
v
signature certificat 566A...
|
v
empreinte absente de trustedSigners
|
X
refus
Alors que la bonne politique est :
Microsoft
|
+-----------+-----------+
| |
ancien certificat nouveau certificat
| |
accepté accepté
Une rotation de certificat ne signifie donc pas automatiquement « supprimer l'ancien ». Elle signifie ici étendre l'ensemble des identités cryptographiques acceptées.
La méthode la plus simple avec le SDK .NET
Il n'est heureusement pas indispensable d'éditer le XML à la main. Avec un SDK .NET suffisamment récent, Microsoft indique d'utiliser :
dotnet nuget trust author Microsoft 9A1B131BEE0605433056A4EA3815478A8E177961A968C6C0027C1093D1FEB630 --algorithm SHA256
La commande met à jour le fichier nuget.config concerné.
Et si, comme je le recommande dans un environnement maîtrisé, vous souhaitez désigner explicitement celui qui doit être modifié :
dotnet nuget trust author Microsoft 9A1B131BEE0605433056A4EA3815478A8E177961A968C6C0027C1093D1FEB630 \
--algorithm SHA256 \
--configfile ./NuGet.config
Sous PowerShell ou cmd.exe, il faudra naturellement adapter la continuation de ligne ou saisir la commande sur une seule ligne.
Je préfère cette méthode à une modification manuelle dès qu'elle peut être utilisée : elle réduit les erreurs de saisie sur une empreinte SHA-256 qui, soyons francs, n'est pas le genre de chaîne que l'on souhaite recopier à la main.
Et dotnet nuget verify ?
Deuxième cas : certains pipelines vérifient explicitement les packages téléchargés. On peut par exemple utiliser :
dotnet nuget verify MonPackage.nupkg
pour vérifier un package signé.
Mais on peut aller plus loin et exiger une empreinte précise :
dotnet nuget verify MonPackage.nupkg \
--certificate-fingerprint 566A31882BE208BE4422F7CFD66ED09F5D4524A5994F50CCC8B05EC0528C1353
Dans ce cas, un nouveau package Microsoft signé avec le certificat de septembre 2026 ne correspondra évidemment plus à cette empreinte.
Là encore, il ne faut pas simplement remplacer l'ancienne valeur.
dotnet nuget verify accepte plusieurs options --certificate-fingerprint.
On peut donc écrire :
dotnet nuget verify MonPackage.nupkg \
--certificate-fingerprint 3F9001EA83C560D712C24CF213C3D312CB3BFF51EE89435D3430BD06B5D0EECE \
--certificate-fingerprint AA12DA22A49BCE7D5C1AE64CC1F3D892F150DA76140F210ABD2CBFFCA2C18A27 \
--certificate-fingerprint 566A31882BE208BE4422F7CFD66ED09F5D4524A5994F50CCC8B05EC0528C1353 \
--certificate-fingerprint 9A1B131BEE0605433056A4EA3815478A8E177961A968C6C0027C1093D1FEB630
C'est particulièrement important si cette commande apparaît dans un script CI/CD.
Le vrai risque : le restore qui casse sans modification du code
C'est finalement ce que je trouve intéressant dans cette annonce.
On peut avoir :
et pourtant voir un pipeline échouer simplement parce qu'un package nouvellement restauré est désormais signé avec un certificat qui n'existe pas dans la politique de confiance locale.
Le scénario peut ressembler à ceci :
Hier
|
dotnet restore
|
package Microsoft signé
certificat autorisé
|
v
OK
Aujourd'hui
|
dotnet restore
|
nouveau package Microsoft
nouveau certificat
|
certificat absent de
trustedSigners
|
v
NU3034
Ce genre d'incident est trompeur parce que rien n'a nécessairement changé dans l'application. C'est l'environnement de confiance de la chaîne de build qui a changé.
Et c'est précisément pour cette raison que les dépendances, les feeds NuGet et leurs règles de validation font partie de l'infrastructure de build au même titre que le SDK ou MSBuild.
Comment savoir rapidement si votre entreprise est concernée ?
Je commencerais par chercher les éléments suivants dans les dépôts et dans les configurations des agents de build :
signatureValidationMode
trustedSigners
certificateFingerprint
--certificate-fingerprint
dotnet nuget verify
nuget verify
La présence de :
<add key="signatureValidationMode" value="require" />
mérite évidemment une attention immédiate.
De même pour :
<trustedSigners>
Dans une organisation importante, attention à ne pas chercher uniquement dans le nuget.config placé à la racine de la solution.
NuGet combine potentiellement plusieurs niveaux de configuration. Une règle peut donc provenir d'un fichier situé en dehors du dépôt lui-même et être appliquée sur les postes de développement ou sur les agents CI.
C'est même souvent là que les surprises commencent.
CI/CD : GitHub Actions, Azure DevOps, Jenkins…
Le moteur CI utilisé n'a finalement que peu d'importance.
GitHub Actions, Azure DevOps, Jenkins ou un agent interne ne sont affectés que dans la mesure où les commandes exécutées par le pipeline le sont.
Prenons un pipeline extrêmement simplifié :
steps:
- script: dotnet restore
displayName: Restore
- script: dotnet build --no-restore
displayName: Build
- script: dotnet test --no-build
displayName: Tests
Si le dotnet restore utilise un nuget.config imposant les signataires autorisés et que le nouveau certificat Microsoft n'y figure pas, le pipeline peut échouer dès la première étape.
Le correctif n'est alors ni dans le csproj, ni dans le code C#, ni dans le YAML lui-même.
Il est dans la politique NuGet.
C'est une distinction qui peut faire gagner pas mal de temps lorsque l'incident survient.
Faut-il installer le nouveau certificat dans le magasin Windows ?
C'est une confusion assez naturelle, car dès que l'on parle de X.509 sous Windows on pense immédiatement à certmgr.msc, certlm.msc, TrustedPeople, TrustedRoot, PowerShell ou certutil.
Mais ce n'est pas ce que demande Microsoft pour cette rotation.
Dans le scénario qui nous intéresse ici, l'autorisation du signataire est définie dans la politique NuGet via l'empreinte du certificat.
Il ne faut donc pas transformer cette opération en déploiement sauvage du certificat dans Trusted Root Certification Authorities.
Ce serait au mieux inutile et, au pire, une modification beaucoup plus large de la politique de confiance de la machine que ce dont NuGet a réellement besoin. Une règle de sécurité devrait toujours être appliquée au niveau le plus étroit possible.
Ici :
Je fais confiance à ce certificat
pour identifier cet auteur NuGet
est beaucoup plus précis que :
Je modifie globalement
les autorités auxquelles fait confiance
cette machine.
Ce n'est pas du tout la même chose.
Et si nous n'avons jamais configuré trustedSigners ?
Alors il ne faut probablement rien faire.
C'est important de le répéter, parce que les annonces de sécurité ont parfois un effet secondaire regrettable : elles déclenchent des modifications « préventives » sur des machines qui n'étaient pas concernées. Ajouter des règles de confiance que l'on ne comprend pas n'améliore pas la sécurité. Avant toute intervention, je suivrais donc ce raisonnement :
Utilisons-nous trustedSigners ?
|
+----+----+
| |
NON OUI
| |
v v
rien à faire la nouvelle empreinte
Microsoft est-elle présente ?
|
+----+----+
| |
OUI NON
| |
v v
OK l'ajouter
Même raisonnement pour dotnet nuget verify.
Une bonne occasion de regarder enfin nos nuget.config
Cette rotation de certificat est finalement assez banale. Les certificats expirent. Les clés tournent. Les fournisseurs modifient leurs infrastructures. Il n'y a là rien d'exceptionnel. Mais elle met en lumière quelque chose que je trouve beaucoup plus intéressant : combien d'équipes savent réellement quelles règles NuGet sont appliquées lors de leurs builds ?
Nous surveillons généralement :
Mais beaucoup moins :
-
les politiques de signature ;
-
les signataires approuvés ;
-
les configurations NuGet héritées ;
-
les différences entre un poste développeur et un agent CI ;
-
les scripts de vérification ajoutés il y a trois ans et oubliés depuis.
Or tout cela fait partie de la reproductibilité d'un build.
Deux machines exécutant exactement :
dotnet restore
ne suivent pas nécessairement la même politique si elles ne chargent pas les mêmes configurations NuGet. À mes yeux, c'est probablement la leçon la plus intéressante de cette petite rotation de certificat.
Ce que je ferais concrètement
Si je devais vérifier aujourd'hui un environnement .NET professionnel, je resterais très pragmatique :
-
rechercher trustedSigners et signatureValidationMode dans les configurations NuGet ;
-
rechercher les utilisations de dotnet nuget verify et nuget verify dans les scripts et pipelines ;
-
identifier les vérifications fondées sur les empreintes Microsoft ;
-
ajouter la nouvelle empreinte SHA-256 sans supprimer les anciennes ;
-
exécuter un vrai dotnet restore sur les agents concernés ;
-
conserver la configuration dans le contrôle de source lorsque cela est possible.
Ce dernier point est important.
Une politique de sécurité présente uniquement sur un serveur de build et modifiée manuellement par un administrateur est difficile à auditer et encore plus difficile à reproduire. Lorsque le contexte le permet, je préfère de loin :
Repository
|
+-- NuGet.config
|
+-- src/
|
+-- tests/
|
+-- pipeline.yml
à une configuration invisible dispersée dans les machines.
Ce qui peut être versionné, revu et audité devrait généralement l'être.
En conclusion
Il n'y a pas ici de faille spectaculaire, ni d'urgence généralisée dans l'écosystème .NET.
Microsoft fait tourner son certificat de signature d'auteur pour ses packages NuGet, et la plupart des développeurs ne verront absolument aucune différence.
En revanche, si votre organisation utilise une politique stricte de signataires approuvés ou vérifie explicitement les empreintes des certificats Microsoft, il faut ajouter le nouveau certificat à la liste des certificats autorisés.
L'empreinte SHA-256 à ajouter est :
9A1B131BEE0605433056A4EA3815478A8E177961A968C6C0027C1093D1FEB630
Et je souligne une dernière fois le point le plus facile à rater :
Ajoutez cette empreinte. Ne remplacez pas les anciennes.
Les anciens packages restent signés avec leurs anciens certificats.
Au-delà de cette modification ponctuelle, j'y vois surtout une bonne occasion de regarder d'un peu plus près nos nuget.config.
La supply chain logicielle n'est pas uniquement constituée des packages que nous choisissons d'utiliser. Elle comprend également les règles qui déterminent qui nous autorisons à nous fournir ces packages. Et cette partie-là mérite probablement davantage d'attention qu'on ne lui en accorde habituellement.
Références
-
Microsoft .NET Blog — Microsoft is updating its author-signing certificate starting September 23, 2026, NuGet Team, 23 septembre 2026.
-
Microsoft Learn — référence du fichier nuget.config, section trustedSigners.
-
Microsoft Learn — commande dotnet nuget verify.
-
Microsoft Learn — gestion des limites de confiance pour les packages signés.
Stay Tuned!