CryptographicException 'Keyset n'existe pas', mais uniquement via WCF


157

J'ai du code qui appelle un service Web tiers sécurisé à l'aide de la certification X.509.

Si j'appelle le code directement (en utilisant un test unitaire), cela fonctionne sans aucun problème.

Une fois déployé, ce code sera appelé via un service WCF. J'ai ajouté un deuxième test unitaire qui appelle le service WCF, mais cela échoue avec un CryptographicExceptionmessage "Keyset does not exist"lorsque j'appelle une méthode sur le service Web tiers.

Je suppose que cela est dû au fait que mon service WCF tentera d'appeler le service Web tiers en utilisant un utilisateur différent de moi-même.

Quelqu'un peut-il apporter un éclairage supplémentaire sur cette question?

Réponses:


168

Ce sera probablement un problème d'autorisations sur le certificat.

Lors de l'exécution d'un test unitaire, vous allez les exécuter dans votre propre contexte utilisateur, qui (en fonction du magasin dans lequel se trouve le certificat client ) aura accès à la clé privée de ce certificat.

Cependant, si votre service WCF est hébergé sous IIS ou en tant que service Windows, il est probable qu'il s'exécutera sous un compte de service (service réseau, service local ou autre compte restreint).

Vous devrez définir les autorisations appropriées sur la clé privée pour autoriser ce compte de service à y accéder. MSDN a les détails


Running calcs m'a aidé pour un problème complètement différent merci
John

3
Je lance mon APP en tant qu'administrateur, le problème est parti.
derek

1
+1 pour la documentation MSDN et les étapes répertoriées s'appliquent même à une application Web
Naren

L'ajout de "SERVICE RÉSEAU" aux autorisations de sécurité du certificat a résolu ce problème pour moi, merci!
OpMt le

276

Cela est probablement dû au fait que l'utilisateur IIS n'a pas accès à la clé privée de votre certificat. Vous pouvez définir cela en suivant ces étapes ...

  1. Démarrer -> Exécuter -> MMC
  2. Fichier -> Ajouter / supprimer un composant logiciel enfichable
  3. Ajouter le composant logiciel enfichable Certificats
  4. Sélectionnez Compte d'ordinateur, puis cliquez sur suivant
  5. Sélectionnez Ordinateur local (par défaut), puis cliquez sur Terminer
  6. Sur le panneau de gauche à partir de la racine de la console, accédez à Certificats (ordinateur local) -> Personnel -> Certificats
  7. Votre certificat sera probablement ici.
  8. Faites un clic droit sur votre certificat -> Toutes les tâches -> Gérer les clés privées
  9. Définissez ici vos paramètres de clé privée.

1
A noter que ce n'est pas une option sur Server 2003, à moins que mon environnement ne soit configuré de manière farfelue. Cependant, je peux le faire sur Windows 7.
Shawn Hubbard

ce que vous voulez dire avec la clé privée définie ici ?? Je veux dire que vous ne pouvez ajouter que l'utilisateur avec le droit d'accès !?
mastervv

10
Merci, je voulais juste souligner que si vous utilisez iis7.5 et que le pool d'applications s'exécute en tant qu'applicationpoolidentity, vous devrez donner les autorisations utilisateur IIS AppPool \ DefaultAppPool sur le fichier. Cela a résolu le problème pour moi.
Ronen Festinger le

25
J'ai dû donner la permission à IIS_IUSRS pour que cela fonctionne pour moi.
TrueEddie

1
si vous obtenez cela lors de l'exécution d'IIS express, vous devez donner vos propres autorisations de connexion.
Jez

38

J'ai eu un problème identique hier soir. Les autorisations sur la clé privée ont été définies correctement, tout allait apparemment bien sauf l'erreur Keyset n'existe pas. En fin de compte, il s'est avéré que le certificat était d'abord importé dans le magasin d'utilisateurs actuel, puis déplacé vers le magasin de machines local. Cependant, cela n'a pas déplacé la clé privée, qui était toujours dans le

C: \ Documents et paramètres \ Administrateur ...

au lieu de

C: \ Documents et paramètres \ Tous les utilisateurs ...

Bien que les autorisations sur la clé aient été correctement définies, ASPNET ne pouvait pas y accéder. Lorsque nous avons réimporté le certificat afin que la clé privée soit placée dans la branche Tous les utilisateurs, le problème a disparu.


Même problème. Microsoft doit arrêter de laisser les bozos de sécurité gérer l'asile.
Paul Stovell

2
Après 3 heures perdues, cela résout mon problème - Merci. J'ai utilisé l' exemple FindPrivateKey et je ne savais pas pourquoi il semblait se trouver dans le keystore de mon utilisateur, même lorsqu'il apparaissait dans LocalMachine via le composant logiciel enfichable MMC.
Rob Potter

Je t'achèterais une bière pour les heures perdues à jouer avec les autorisations comme toutes les autres réponses me le disaient.
Scott Scowden

Merci merci merci! J'ai perdu environ 2,5 heures de ma vie grâce à cet horrible problème et je suis sûr que j'aurais perdu 2,5 jours si je n'avais pas vu cela.
Frank Tzanabetis

J'ai eu le même problème à l'envers. D'abord installé dans Local Machine, puis dans Current User. La suppression de tous les certificats des deux magasins et la réinstallation sous Utilisateur actuel l'ont corrigé.
Bart Verkoeijen

24

Pour résoudre le problème «Le jeu de clés n'existe pas» lors de la navigation depuis IIS: Cela peut être pour l'autorisation privée

Pour afficher et donner l'autorisation:

  1. Exécuter> mmc> oui
  2. cliquez sur le fichier
  3. Cliquez sur Ajouter / supprimer un composant logiciel enfichable…
  4. Double-cliquez sur le certificat
  5. Compte d'ordinateur
  6. Prochain
  7. terminer
  8. D'accord
  9. Cliquez sur Certificats (ordinateur local)
  10. Cliquez sur Personnel
  11. Cliquez sur Certificats

Pour donner la permission:

  1. Faites un clic droit sur le nom du certificat
  2. Toutes les tâches> Gérer les clés privées…
  3. Ajouter et donner le privilège (ajouter IIS_IUSRS et lui donner le privilège fonctionne pour moi)

1
Si vous exécutez sous un pool d'applications, ajoutez cet utilisateur à la place "IIS AppPool \ DefaultAppPool"
Sameer Alibhai

Cela m'a aidé aussi. Dès que j'ai donné les autorisations à IIS_IUSRS, cela a commencé à fonctionner.
Andrej Mohar

18

J'ai eu le même problème en essayant d'exécuter l'application WCF à partir de Visual Studio. Résolu le problème en exécutant Visual Studio en tant qu'administrateur.


11

J'ai rencontré ce problème, mes certificats avaient une clé privée mais j'obtenais cette erreur ( "Le jeu de clés n'existe pas" )

Cause: Votre site Web fonctionne sous le compte "Services réseau" ou dispose de privilèges inférieurs.

Solution : modifiez l'identité du pool d'applications sur «Système local», réinitialisez IIS et vérifiez à nouveau. Si cela commence à fonctionner, il s'agit d'un problème d'autorisation / de privilège moindre, vous pouvez également emprunter l'identité en utilisant d'autres comptes.


8

Totalement frustrant, j'ai eu le même problème et j'ai essayé la plupart de ce qui précède. Le certificat exporté avait correctement les autorisations de lecture du fichier C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys, mais il s'avère qu'il n'avait pas l'autorisation sur le dossier. Je l'ai ajouté et cela a fonctionné


J'ai essayé tellement de choses pour résoudre ce problème, mais celle-ci a fait l'affaire!
Gyum Fox

wow - je ne m'attendais pas à ce que cela fonctionne, mais c'est le cas. J'ai ajouté IISAPPPool\www.mywebsite.comquel est le nom d'utilisateur Windows pour mon appool et cela a fonctionné :-)
Simon_Weaver

quelqu'un sait pourquoi cela fonctionne? est quelque chose de corrompu parce que c'est assez obscur
Simon_Weaver

Ne fais pas ça! Le serveur entre dans le "mauvais état" où les certificats sont importés et apparaissent avec le type de fournisseur "Microsoft Software KSP" lorsque le dossier ..RSA \ MachineKeys a ses autorisations de base modifiées. Plus de détails reddit.com/r/sysadmin/comments/339ogk/… .
Dhanuka777

3

J'ai aussi un problème exactement similaire. J'ai utilisé la commande

findprivatekey root localmachine -n "CN="CertName" 

le résultat montre que la clé privée se trouve dans le dossier c: \ ProgramData au lieu de C: \ Documents and settngs \ All users ..

Lorsque je supprime la clé du dossier c: \ ProgramData, réexécutez la commande findPrivatekey échoue. c'est à dire. il ne trouve pas la clé.

Mais si je recherche la même clé retournée par la commande précédente, je peux toujours trouver la clé dans

C: \ Documents et paramètres \ Tous les utilisateurs ..

Donc, à ma connaissance, IIS ou le WCF hébergé ne trouve pas la clé privée de C: \ Documents and settngs \ All users ..


2
Salut ce lien vous dire comment résoudre ce problème et également localiser le findprivatekey outil: blogs.msdn.microsoft.com/dsnotes/2015/08/13/...
Tahir Khalid

3

J'obtenais l'erreur: CryptographicException «Keyset n'existe pas» lorsque j'exécute l'application MVC.

La solution était: pour donner accès aux certificats personnels au compte sous lequel le pool d'applications s'exécute. Dans mon cas, il s'agissait d'ajouter IIS_IUSRS et de choisir le bon emplacement a résolu ce problème.

RC on the Certificate - > All tasks -> Manage Private Keys -> Add->  
For the From this location : Click on Locations and make sure to select the Server name. 
In the Enter the object names to select : IIS_IUSRS and click ok. 

2

La réponse de Steve Sheldon a résolu le problème pour moi, cependant, comme je script des autorisations de certificat sans interface graphique, j'avais besoin d'une solution scriptable. J'ai eu du mal à trouver où ma clé privée était stockée. La clé privée n'était pas -C:\ProgramData\Microsoft\Crypto\RSA\MachineKeysdedans, finalement j'ai trouvé qu'elle était réellement dedans C:\ProgramData\Microsoft\Crypto\Keys. Ci-dessous, je décris comment j'ai découvert cela:

J'ai essayé FindPrivateKeymais il n'a pas pu trouver la clé privée, et en utilisant PowerShell, il $cert.privatekey.cspkeycontainerinfo.uniquekeycontainernameétait nul / vide.

Heureusement, certutil -store myj'ai répertorié le certificat et m'a donné les détails dont j'avais besoin pour scénariser la solution.

================ Certificate 1 ================ Serial Number: 162f1b54fe78c7c8fa9df09 Issuer: CN=*.internal.xxxxxxx.net NotBefore: 23/08/2019 14:04 NotAfter: 23/02/2020 14:24 Subject: CN=*.xxxxxxxnet Signature matches Public Key Root Certificate: Subject matches Issuer Cert Hash(sha1): xxxxa5f0e9f0ac8b7dd634xx Key Container = {407EC7EF-8701-42BF-993F-CDEF8328DD} Unique container name: 8787033f8ccb5836115b87acb_ca96c65a-4b42-a145-eee62128a ##* ^-- filename for private key*## Provider = Microsoft Software Key Storage Provider Private key is NOT plain text exportable Encryption test passed CertUtil: -store command completed successfully.

J'ai ensuite scanné le c\ProgramData\Microsoft\Crypto\dossier et trouvé le fichier 8787033f8ccb5836115b87acb_ca96c65a-4b42-a145-eee62128a dans C: \ ProgramData \ Microsoft \ Crypto \ Keys .

Donner à mon compte de service un accès en lecture à ce fichier a résolu les problèmes pour moi


1
L'utilisation de "certutil -store my" a été la clé pour résoudre mon problème. J'ai utilisé le "Nom de conteneur unique" pour localiser le fichier et Sysinternals Process Monitor pour dépanner une erreur "Accès refusé" sur le fichier de certificat. Dans mon cas, j'ai dû fournir un accès en lecture au fichier de certificat pour l'utilisateur NT Authority \ IUSR.
hsop

1

J'ai trouvé des informations manquantes qui m'ont aidé à obtenir mon service WCF avec la sécurité au niveau du message au-delà du "Keyset n'existe pas" que j'ai continué à rencontrer malgré l'octroi d'autorisations à toutes les clés générées à partir des exemples sur Internet.

J'ai finalement importé la clé privée dans le magasin de personnes de confiance sur la machine locale, puis j'ai accordé à la clé privée les autorisations appropriées.

Cela a rempli les espaces vides pour moi et m'a finalement permis d'implémenter le service WCF avec la sécurité au niveau du message. Je construis un WCF qui doit être conforme HIPPA.


1

Je viens de réinstaller mon certificat sur la machine locale et cela fonctionne bien


0

Si vous utilisez ApplicationPoolIdentity pour votre pool d'applications, vous pouvez avoir des problèmes avec la spécification de l'autorisation pour cet utilisateur «virtuel» dans l'éditeur de registre (il n'y a pas un tel utilisateur dans le système).

Alors, utilisez subinacl - un outil de ligne de commande qui permet de définir des ACL de registre, ou quelque chose comme ça.


0

Je voulais juste ajouter une réponse de vérification de cohérence. J'obtenais exactement la même erreur même après avoir installé les certificats dans les bons magasins sur mes machines et avoir tous les bons privilèges de sécurité pour le client. Il s'avère que j'ai confondu mon clientCertificate et mon certificat de service. Si vous avez essayé tout ce qui précède, je vérifierais que vous avez bien compris ces deux éléments. Une fois que j'ai fait cela, mon application a appelé avec succès le service Web. Encore une fois, juste un vérificateur de santé mentale.


0

Reçu cette erreur lors de l'utilisation du Fedlet openAM sur IIS7

La modification du compte d'utilisateur pour le site Web par défaut a résolu le problème. Idéalement, vous voudriez qu'il s'agisse d'un compte de service. Peut-être même le compte de l'IUSR. Suggérez de rechercher des méthodes de durcissement IIS pour le clouer complètement.


0

J'ai touché cela dans mon projet de structure de service après l'expiration et la rotation du certificat utilisé pour l'authentification par rapport à notre coffre de clés, ce qui a changé l'empreinte numérique. J'ai eu cette erreur parce que j'avais manqué la mise à jour de l'empreinte numérique dans le fichier applicationManifest.xml dans ce bloc qui fait précisément ce que les autres réponses ont suggéré - donner des autorisations de SERVICE RÉSEAU (que tous mes ex exécutent en tant que configuration standard pour le cluster azure servicefabric) accéder à l'emplacement du magasin LOCALMACHINE \ MY cert.

Notez la valeur d'attribut "X509FindValue".

<!-- this block added to allow low priv processes (such as service fabric processes) that run as NETWORK SERVICE to read certificates from the store -->
  <Principals>
    <Users>
      <User Name="NetworkService" AccountType="NetworkService" />
    </Users>
  </Principals>
  <Policies>
    <SecurityAccessPolicies>
      <SecurityAccessPolicy ResourceRef="AzureKeyvaultClientCertificate" PrincipalRef="NetworkService" GrantRights="Full" ResourceType="Certificate" />
    </SecurityAccessPolicies>
  </Policies>
  <Certificates>
    <SecretsCertificate X509FindValue="[[THIS KEY ALSO NEEDS TO BE UPDATED]]" Name="AzureKeyvaultClientCertificate" />
  </Certificates>
  <!-- end block -->


0

C'est la seule solution qui a fonctionné pour moi.

    // creates the CspParameters object and sets the key container name used to store the RSA key pair
    CspParameters cp = new CspParameters();
    cp.KeyContainerName = "MyKeyContainerName"; //Eg: Friendly name

    // instantiates the rsa instance accessing the key container MyKeyContainerName
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);
    // add the below line to delete the key entry in MyKeyContainerName
    // rsa.PersistKeyInCsp = false;

    //writes out the current key pair used in the rsa instance
    Console.WriteLine("Key is : \n" + rsa.ToXmlString(true));

Référence 1

Référence 2


0
This issue is got resolved after adding network service role.

CERTIFICATE ISSUES 
Error :Keyset does not exist means System might not have access to private key
Error :Enveloped data  
Step 1:Install certificate in local machine not in current user store
Step 2:Run certificate manager
Step 3:Find your certificate in the local machine tab and right click manage privatekey and check in allowed personnel following have been added:
a>Administrators
b>yourself
c>'Network service'
And then provide respective permissions.

## You need to add 'Network Service' and then it will start working.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.