CryptographicException 'Keyset existiert nicht', sondern nur über WCF

157

Ich habe einen Code, der einen Webdienst eines Drittanbieters aufruft, der mit der X.509-Zertifizierung gesichert ist.

Wenn ich den Code direkt aufrufe (mit einem Unit-Test), funktioniert er problemlos.

Bei der Bereitstellung wird dieser Code über einen WCF-Dienst aufgerufen. Ich habe einen zweiten Komponententest hinzugefügt, der den WCF-Dienst aufruft. Dies schlägt jedoch mit einer CryptographicExceptionMeldung fehl , "Keyset does not exist"wenn ich eine Methode für den Webdienst eines Drittanbieters aufrufe.

Ich gehe davon aus, dass dies darauf zurückzuführen ist, dass mein WCF-Dienst versucht, den Webdienst eines Drittanbieters mit einem anderen Benutzer als mir selbst aufzurufen.

Kann jemand zusätzliches Licht auf dieses Thema werfen?

Richard Ev
quelle

Antworten:

168

Es wird wahrscheinlich ein Berechtigungsproblem für das Zertifikat sein.

Wenn Sie einen Komponententest ausführen, führen Sie diese in Ihrem eigenen Benutzerkontext aus, der (abhängig davon, in welchem ​​Speicher sich das Clientzertifikat befindet) Zugriff auf den privaten Schlüssel dieses Zertifikats hat.

Wenn Ihr WCF-Dienst jedoch unter IIS oder als Windows-Dienst gehostet wird, wird er wahrscheinlich unter einem Dienstkonto (Netzwerkdienst, lokaler Dienst oder einem anderen eingeschränkten Konto) ausgeführt.

Sie müssen die entsprechenden Berechtigungen für den privaten Schlüssel festlegen, damit dieses Dienstkonto darauf zugreifen kann. MSDN hat die Details

Blasrohrpfeil
quelle
Das Ausführen von Berechnungen half mir für ein völlig anderes Problem, danke
John
3
Ich führe meine APP als Administrator aus, wenn das Problem behoben ist.
Derek
1
+1 für die MSDN-Dokumentation und die aufgeführten Schritte gelten auch für eine Webanwendung
Naren
Das Hinzufügen von "NETWORK SERVICE" zu den Zertifikatsicherheitsberechtigungen hat dies für mich behoben, danke!
OpMt
276

Dies liegt höchstwahrscheinlich daran, dass der IIS-Benutzer keinen Zugriff auf den privaten Schlüssel für Ihr Zertifikat hat. Sie können dies einstellen, indem Sie die folgenden Schritte ausführen ...

  1. Start -> Ausführen -> MMC
  2. Datei -> Snapin hinzufügen / entfernen
  3. Fügen Sie das Zertifikat-Snap-In hinzu
  4. Wählen Sie Computerkonto und klicken Sie auf Weiter
  5. Wählen Sie Lokaler Computer (Standardeinstellung) und klicken Sie dann auf Fertig stellen
  6. Navigieren Sie im linken Bereich des Konsolenstamms zu Zertifikate (lokaler Computer) -> Persönlich -> Zertifikate
  7. Ihr Zertifikat wird höchstwahrscheinlich hier sein.
  8. Klicken Sie mit der rechten Maustaste auf Ihr Zertifikat -> Alle Aufgaben -> Private Schlüssel verwalten
  9. Stellen Sie hier Ihre Einstellungen für den privaten Schlüssel ein.
Steve Sheldon
quelle
1
Es ist erwähnenswert, dass dies unter Server 2003 keine Option ist, es sei denn, meine Umgebung ist verrückt konfiguriert. Ich kann dies jedoch unter Windows 7 tun.
Shawn Hubbard
Was meinst du mit gesetztem privaten Schlüssel hier? Ich meine, Sie können nur den Benutzer mit Zugriffsrecht hinzufügen!?
Mastervv
10
Vielen Dank, ich wollte nur darauf hinweisen, dass Sie IIS AppPool \ DefaultAppPool-Benutzerberechtigungen für die Datei erteilen müssen, wenn Sie iis7.5 verwenden und der Anwendungspool als Anwendungspoolidentität ausgeführt wird. Dies hat das Problem für mich behoben.
Ronen Festinger
25
Ich musste IIS_IUSRS die Erlaubnis geben, damit es für mich funktioniert.
TrueEddie
1
Wenn Sie dies während der Ausführung von IIS Express erhalten, müssen Sie Ihre eigenen Anmeldeberechtigungen angeben.
Jez
38

Ich hatte letzte Nacht ein identisches Problem. Die Berechtigungen für den privaten Schlüssel wurden korrekt festgelegt. Anscheinend war alles in Ordnung, außer dass der Keyset-Fehler nicht vorhanden ist. Am Ende stellte sich heraus, dass das Zertifikat zuerst in den aktuellen Benutzerspeicher importiert und dann in den lokalen Computerspeicher verschoben wurde. Der private Schlüssel, der sich noch im

C: \ Dokumente und Einstellungen \ Administrator ...

anstatt

C: \ Dokumente und Einstellungen \ Alle Benutzer ...

Obwohl die Berechtigungen für den Schlüssel korrekt festgelegt wurden, konnte ASPNET nicht darauf zugreifen. Als wir das Zertifikat erneut importierten, sodass der private Schlüssel im Zweig Alle Benutzer abgelegt wurde, verschwand das Problem.

Željko Tanović
quelle
Gleiches Problem. Microsoft muss aufhören, die Sicherheitsbeauftragten das Asyl betreiben zu lassen.
Paul Stovell
2
Nach 3 verlorenen Stunden löst dies mein Problem - Danke. Ich habe das FindPrivateKey- Beispiel verwendet und war verwirrt, warum es im Keystore meines Benutzers zu sein schien, selbst wenn es in LocalMachine über das MMC-Snap-In angezeigt wurde.
Rob Potter
Ich würde dir ein Bier für die Stunden kaufen, in denen ich mit Berechtigungen herumgespielt habe, wie es mir jede andere Antwort gesagt hat.
Scott Scowden
Danke danke danke! Ich habe ungefähr 2,5 Stunden meines Lebens dank dieses schrecklichen Problems verloren und ich bin sicher, ich hätte 2,5 Tage verloren, wenn ich das nicht gesehen hätte.
Frank Tzanabetis
Ich hatte das gleiche Problem umgekehrt. Zuerst auf dem lokalen Computer installiert, dann unter Aktueller Benutzer. Das Entfernen aller Zertifikate aus beiden Filialen und die Neuinstallation unter Aktueller Benutzer haben das Problem behoben.
Bart Verkoeijen
24

So lösen Sie das Problem "Keyset existiert nicht" beim Surfen über IIS: Möglicherweise ist dies eine private Berechtigung

So zeigen Sie die Berechtigung an und geben sie ab:

  1. Führen Sie> mmc> yes aus
  2. Klicken Sie auf Datei
  3. Klicken Sie auf Snap-In hinzufügen / entfernen.
  4. Doppelklicken Sie auf Zertifikat
  5. Computerkonto
  6. Nächster
  7. Fertig
  8. OK
  9. Klicken Sie auf Zertifikate (lokaler Computer)
  10. Klicken Sie auf Persönlich
  11. Klicken Sie auf Zertifikate

Um die Erlaubnis zu geben:

  1. Klicken Sie mit der rechten Maustaste auf den Namen des Zertifikats
  2. Alle Aufgaben> Private Schlüssel verwalten…
  3. Fügen Sie das Privileg hinzu und geben Sie es (das Hinzufügen von IIS_IUSRS und das Erteilen des Privilegs funktioniert für mich)
Md. Ilyas Hasan Mamun
quelle
1
Wenn Sie unter einem App-Pool ausgeführt werden, fügen Sie diesen Benutzer stattdessen "IIS AppPool \ DefaultAppPool"
Sameer Alibhai
Das hat mir auch geholfen. Sobald ich IIS_IUSRS die Berechtigungen erteilt hatte, begann es zu funktionieren.
Andrej Mohar
18

Hatte das gleiche Problem beim Versuch, die WCF-App in Visual Studio auszuführen. Es wurde behoben, indem Visual Studio als Administrator ausgeführt wurde.

desegel
quelle
11

Ich bin mit diesem Problem konfrontiert. Meine Zertifikate hatten einen privaten Schlüssel, aber ich habe diesen Fehler erhalten ( "Keyset existiert nicht" ).

Ursache: Ihre Website wird unter dem Konto "Netzwerkdienste" ausgeführt oder verfügt über weniger Berechtigungen.

Lösung : Ändern Sie die Identität des Anwendungspools in "Lokales System", setzen Sie IIS zurück und überprüfen Sie es erneut. Wenn es funktioniert, handelt es sich um ein Problem mit Berechtigungen / weniger Berechtigungen. Sie können sich dann auch als andere Konten ausgeben.

Vaibhav. Inspiriert
quelle
8

Völlig frustrierend, hatte ich das gleiche Problem und versuchte die meisten der oben genannten. Das exportierte Zertifikat hatte die Berechtigung zum Einlesen der Datei C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys, es stellte sich jedoch heraus, dass es keine Berechtigung für den Ordner hatte. Fügte es hinzu und es funktionierte

Köter
quelle
Ich habe so viele Dinge versucht, um dieses Problem zu lösen, aber dieser hat es geschafft!
Gyum Fox
wow - hatte NICHT erwartet, dass das funktioniert, aber es tat es. Ich habe hinzugefügt, IISAPPPool\www.mywebsite.comwelches der Windows-Benutzername für meinen Appool ist und es hat funktioniert :-)
Simon_Weaver
weiß jemand warum das funktioniert? ist etwas beschädigt, weil dies ziemlich dunkel ist
Simon_Weaver
Tu das nicht! Der Server befindet sich im "fehlerhaften Zustand", in dem Zertifikate importiert werden und mit dem Anbietertyp "Microsoft Software KSP" angezeigt werden, wenn die Basisberechtigungen des Ordners ..RSA \ MachineKeys geändert werden. Weitere Details reddit.com/r/sysadmin/comments/339ogk/… .
Dhanuka777
3

Ich habe auch genau ein ähnliches Problem. Ich habe den Befehl verwendet

findprivatekey root localmachine -n "CN="CertName" 

Das Ergebnis zeigt, dass sich der private Schlüssel im Ordner c: \ ProgramData anstelle von C: \ Documents and Settngs \ All users befindet.

Wenn ich den Schlüssel aus dem Ordner c: \ ProgramData lösche, wird der Befehl findPrivatekey erneut erfolgreich ausgeführt. dh. es findet den Schlüssel nicht.

Aber wenn ich den gleichen Schlüssel suche, der von einem früheren Befehl zurückgegeben wurde, kann ich den Schlüssel immer noch finden

C: \ Dokumente und Einstellungen \ Alle Benutzer ..

Nach meinem Verständnis findet IIS oder die gehostete WCF den privaten Schlüssel nicht unter C: \ Dokumente und Einstellungen \ Alle Benutzer.

user1773822
quelle
2
Hallo, dieser Link zeigt Ihnen, wie Sie dieses Problem beheben und das findprivatekey- Tool finden können: blogs.msdn.microsoft.com/dsnotes/2015/08/13/…
Tahir Khalid
3

Ich habe die Fehlermeldung erhalten: CryptographicException 'Keyset existiert nicht', wenn ich die MVC-Anwendung ausführe.

Die Lösung bestand darin, dem Konto, unter dem der Anwendungspool ausgeführt wird, Zugriff auf die persönlichen Zertifikate zu gewähren. In meinem Fall war es das Hinzufügen von IIS_IUSRS und die Auswahl des richtigen Speicherorts, um dieses Problem zu beheben.

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. 
Dev
quelle
2

Die Antwort von Steve Sheldon hat das Problem für mich behoben. Da ich jedoch Zertifikatsberechtigungen ohne GUI schreibe, brauchte ich eine skriptfähige Lösung. Ich bemühte mich herauszufinden, wo mein privater Schlüssel gespeichert war. Der private Schlüssel war nicht in -C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys, schließlich stellte ich fest, dass er tatsächlich in war C:\ProgramData\Microsoft\Crypto\Keys. Im Folgenden beschreibe ich, wie ich das herausgefunden habe:

Ich habe es versucht, FindPrivateKeyaber es konnte den privaten Schlüssel nicht finden, und mit Powershell $cert.privatekey.cspkeycontainerinfo.uniquekeycontainernamewar das null / leer.

Zum Glück certutil -store myhabe ich das Zertifikat aufgelistet und mir die Details gegeben, die ich zum Schreiben der Lösung benötigte.

================ 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.

Ich habe dann den c\ProgramData\Microsoft\Crypto\Ordner gescannt und die Datei 8787033f8ccb5836115b87acb_ca96c65a-4b42-a145-eee62128a in C: \ ProgramData \ Microsoft \ Crypto \ Keys gefunden .

Indem ich meinem Dienstkonto Lesezugriff auf diese Datei gewährte, wurden die Probleme für mich behoben

Dai Bok
quelle
1
Die Verwendung von "certutil -store my" war der Schlüssel zur Lösung meines Problems. Ich habe den "eindeutigen Containernamen" verwendet, um die Datei zu finden, und Sysinternals Process Monitor, um einen Fehler "Zugriff verweigert" in der Zertifikatdatei zu beheben. In meinem Fall musste ich dem Benutzer NT Authority \ IUSR Lesezugriff auf die Zertifikatdatei gewähren.
hsop
1

Ich habe einige fehlende Informationen gefunden, die mir geholfen haben, meinen WCF-Dienst mit Sicherheit auf Nachrichtenebene über das "Keyset existiert nicht" hinaus zu erhalten, auf das ich trotz der Erteilung von Berechtigungen für alle aus den Beispielen im Internet generierten Schlüssel immer wieder gestoßen bin.

Ich habe schließlich den privaten Schlüssel in den Speicher für vertrauenswürdige Personen auf dem lokalen Computer importiert und dem privaten Schlüssel dann die richtigen Berechtigungen erteilt.

Dies füllte die Lücken für mich und ermöglichte mir schließlich, den WCF-Dienst mit Sicherheit auf Nachrichtenebene zu implementieren. Ich baue eine WCF, die HIPPA-konform sein muss.

user1483373
quelle
1

Ich habe gerade mein Zertifikat auf dem lokalen Computer neu installiert und dann funktioniert es einwandfrei

Muni Chittem
quelle
0

Wenn Sie ApplicationPoolIdentity für Ihren Anwendungspool verwenden, haben Sie möglicherweise Probleme beim Angeben der Berechtigung für diesen "virtuellen" Benutzer im Registrierungseditor (es gibt keinen solchen Benutzer im System).

Verwenden Sie also das Befehlszeilentool subinacl , mit dem Sie die Registrierungs-ACLs festlegen können, oder ähnliches.

tyger
quelle
0

Ich wollte nur eine Antwort auf die Überprüfung der geistigen Gesundheit hinzufügen. Ich habe genau den gleichen Fehler erhalten, selbst nachdem ich die Zertifikate in den richtigen Speichern auf meinen Computern installiert hatte und über die richtigen Sicherheitsrechte für den Client verfügte. Es stellte sich heraus, dass ich mein clientCertificate und mein Service Certificate verwechselt habe. Wenn Sie alle oben genannten Punkte ausprobiert haben, würde ich überprüfen, ob Sie diese beiden gerade haben. Sobald ich das getan habe, hat meine Anwendung den Webdienst erfolgreich aufgerufen. Wieder nur ein Sanity Checker.

SoftwareSavant
quelle
0

Dieser Fehler wurde bei Verwendung des openAM-Fedlets auf IIS7 empfangen

Durch Ändern des Benutzerkontos für die Standardwebsite wurde das Problem behoben. Idealerweise möchten Sie, dass dies ein Dienstkonto ist. Vielleicht sogar das IUSR-Konto. Schlagen Sie vor, nach Methoden für die IIS-Härtung zu suchen, um sie vollständig festzunageln.

Jeff Minder
quelle
0

Ich habe dies in meinem Service Fabric-Projekt getroffen, nachdem das zur Authentifizierung bei unserem Schlüsseldepot verwendete Zertifikat abgelaufen und gedreht wurde, wodurch sich der Fingerabdruck geändert hat. Ich habe diesen Fehler erhalten, weil ich die Aktualisierung des Fingerabdrucks in der Datei applicationManifest.xml in diesem Block verpasst habe, der genau das tut, was andere Antworten vorgeschlagen haben - um NETWORK SERVICE (auf dem alle meine Exes als Standardkonfiguration für Azure Servicefabric Cluster ausgeführt werden) zu erteilen Greifen Sie auf den Speicherort LOCALMACHINE \ MY cert zu.

Beachten Sie den Attributwert "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 -->

Sat Thiru
quelle
0

Dies ist die einzige Lösung, die für mich funktioniert hat.

    // 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));

Referenz 1

Referenz 2

CharithJ
quelle
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.
Yuvraj
quelle