CryptographicException 'Keyset non esiste', ma solo tramite WCF


157

Ho del codice che effettua una chiamata a un servizio Web di terzi che è protetto mediante la certificazione X.509.

Se chiamo direttamente il codice (usando un unit test) funziona senza problemi.

Una volta distribuito, questo codice verrà chiamato tramite un servizio WCF. Ho aggiunto un secondo test unit che chiama il servizio WCF, tuttavia questo non riesce con un CryptographicExceptionmessaggio "Keyset does not exist"quando chiamo un metodo sul servizio Web di terze parti.

Presumo che ciò sia dovuto al fatto che il mio servizio WCF tenterà di chiamare il servizio Web di terze parti utilizzando un altro utente.

Qualcuno può far luce su questo problema?

Risposte:


168

Probabilmente sarà un problema di autorizzazioni sul certificato.

Quando si esegue un unit test, si eseguiranno quelli nel proprio contesto utente, che (a seconda dell'archivio in cui si trova il certificato client ) avrà accesso alla chiave privata di quel certificato.

Tuttavia, se il servizio WCF è ospitato in IIS o come servizio Windows, è probabile che verrà eseguito con un account di servizio (servizio di rete, servizio locale o altri account con restrizioni).

Sarà necessario impostare le autorizzazioni appropriate sulla chiave privata per consentire a tale account di servizio di accedervi. MSDN ha i dettagli


L'esecuzione di calc mi ha aiutato per un problema completamente diverso grazie
John,

3
Corro la mia APP come amministratore il problema è andato.
Derek,

1
+1 per la documentazione MSDN e le fasi elencate si applicano anche a un'applicazione Web
Naren,

L'aggiunta di "SERVIZIO DI RETE" alle autorizzazioni di sicurezza del certificato mi ha risolto questo, grazie!
OpMt

276

Ciò è probabilmente dovuto al fatto che l'utente IIS non ha accesso alla chiave privata per il certificato. Puoi impostarlo seguendo questi passaggi ...

  1. Avvia -> Esegui -> MMC
  2. File -> Aggiungi / Rimuovi snapin
  3. Aggiungi lo snap-in certificati
  4. Seleziona Account del computer, quindi fai clic su Avanti
  5. Seleziona Computer locale (impostazione predefinita), quindi fai clic su Fine
  6. Nel pannello di sinistra dalla console principale, accedere a Certificati (computer locale) -> Personale -> Certificati
  7. Molto probabilmente il tuo certificato sarà qui.
  8. Fare clic con il tasto destro del mouse sul certificato -> Tutte le attività -> Gestisci chiavi private
  9. Imposta qui le impostazioni della tua chiave privata.

1
Vale la pena notare che questa non è un'opzione su Server 2003, a meno che il mio ambiente non sia configurato in modo strano. Posso farlo su Windows 7 però.
Shawn Hubbard,

cosa intendi con set chiave privata qui ?? Voglio dire, puoi solo aggiungere l'utente con accesso giusto !?
mastervv,

10
Grazie, volevo solo sottolineare che se si utilizza iis7.5 e il pool di applicazioni viene eseguito come applicationpoolidentity, sarà necessario assegnare le autorizzazioni utente IIS AppPool \ DefaultAppPool al file. Questo ha risolto il problema per me.
Ronen Festinger

25
Ho dovuto dare il permesso a IIS_IUSRS per farlo funzionare per me.
TrueEddie,

1
se si ottiene questo mentre si esegue IIS express, è necessario fornire le proprie autorizzazioni di accesso.
Jez,

38

Ho avuto un problema identico ieri sera. Le autorizzazioni per la chiave privata sono state impostate correttamente, apparentemente tutto andava bene tranne l'errore Keyset non esiste. Alla fine si è scoperto che il certificato è stato prima importato nell'archivio utenti corrente e poi spostato nell'archivio macchine locale. Tuttavia, ciò non ha spostato la chiave privata, che era ancora in

C: \ Documents and settngs \ Administrator ...

invece di

C: \ Documents and settngs \ Tutti gli utenti ...

Sebbene le autorizzazioni per la chiave siano state impostate correttamente, ASPNET non ha potuto accedervi. Quando abbiamo reimportato il certificato in modo che la chiave privata venga inserita nel ramo Tutti gli utenti, il problema è scomparso.


Stesso problema. Microsoft deve smettere di lasciare che i gestori della sicurezza gestiscano l'asilo.
Paul Stovell,

2
Dopo 3 ore perse, questo risolve il mio problema - Grazie. Ho usato l' esempio FindPrivateKey ed ero confuso sul perché apparisse nel keystore del mio utente, anche quando appariva in LocalMachine tramite lo snap-in MMC.
Rob Potter,

Ti comprerei una birra per le ore sprecate a fare casino con le autorizzazioni come mi dicevano tutte le altre risposte.
Scott Scowden,

Grazie, grazie, grazie! Ho perso circa 2,5 ore della mia vita grazie a questo orribile problema e sono sicuro che avrei perso 2,5 giorni se non l'avessi visto.
Frank Tzanabetis,

Ho avuto lo stesso problema al contrario. Installato prima nel computer locale, quindi nell'utente corrente. Rimozione di tutti i certificati da entrambi i negozi e reinstallazione in Utente corrente risolto.
Bart Verkoeijen,

24

Per risolvere il "Keyset non esiste" durante la navigazione da IIS: potrebbe essere per l'autorizzazione privata

Per visualizzare e dare il permesso:

  1. Esegui> mmc> sì
  2. fare clic sul file
  3. Fai clic su Aggiungi / rimuovi snap-in ...
  4. Fare doppio clic sul certificato
  5. Account del computer
  6. Il prossimo
  7. finire
  8. Ok
  9. Fai clic su Certificati (computer locale)
  10. Fai clic su Personale
  11. Fai clic su Certificati

Per dare il permesso:

  1. Fare clic con il tasto destro sul nome del certificato
  2. Tutte le attività> Gestisci chiavi private ...
  3. Aggiungi e dai il privilegio (aggiungere IIS_IUSRS e assegnargli il privilegio funziona per me)

1
Se stai eseguendo un pool di app, aggiungi questo utente invece "IIS AppPool \ DefaultAppPool"
Sameer Alibhai

Anche questo mi ha aiutato. Non appena ho dato a IIS_IUSRS le autorizzazioni, ha iniziato a funzionare.
Andrej Mohar,

18

Si è verificato lo stesso problema durante il tentativo di eseguire l'app WCF da Visual Studio. Risolto eseguendo Visual Studio come amministratore.


11

Ho riscontrato questo problema, i miei certificati avevano la chiave privata ma stavo ottenendo questo errore ( "Keyset non esiste" )

Causa: il sito Web è in esecuzione con l'account "Servizi di rete" o con meno privilegi.

Soluzione : modificare l'identità del pool di applicazioni in "Sistema locale", ripristinare IIS e ricontrollare. Se inizia a funzionare è un problema di autorizzazione / Meno privilegio, puoi impersonare quindi utilizzare anche altri account.


8

Totalmente frustrante, ho avuto lo stesso problema e ho provato la maggior parte di quanto sopra. Il certificato esportato disponeva correttamente delle autorizzazioni per leggere il file C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys, tuttavia risulta che non disponeva dell'autorizzazione per la cartella. Aggiunto e ha funzionato


Ho provato tante cose per risolvere questo problema, ma questo ha funzionato!
Gyum Fox,

wow - NON mi aspettavo che funzionasse ma lo ha fatto. Ho aggiunto IISAPPPool\www.mywebsite.comqual è il nome utente di Windows per il mio appool e ha funzionato :-)
Simon_Weaver

qualcuno sa perché funziona? è qualcosa di corrotto perché questo è piuttosto oscuro
Simon_Weaver

Non farlo! Il server entra nello "stato non valido" in cui vengono importati certificati e visualizzati con il tipo di provider "Software Microsoft KSP" quando la cartella ..RSA \ MachineKeys ha le autorizzazioni di base modificate. Maggiori dettagli reddit.com/r/sysadmin/comments/339ogk/… .
Dhanuka777,

3

Anch'io ho esattamente un problema simile. Ho usato il comando

findprivatekey root localmachine -n "CN="CertName" 

il risultato mostra che la chiave privata si trova nella cartella c: \ ProgramData anziché in C: \ Documents and settngs \ All users ..

Quando elimino la chiave dalla cartella c: \ ProgramData, eseguire nuovamente il comando findPrivatekey non riesce. vale a dire. non trova la chiave.

Ma se cerco la stessa chiave restituita dal comando precedente, riesco ancora a trovare la chiave

C: \ Documents and settngs \ Tutti gli utenti ..

Quindi, per quanto ne so, IIS o il WCF ospitato non trovano la chiave privata da C: \ Documents and settngs \ All users ..


2
Ciao questo link vi dirà come risolvere questo problema e anche individuare il findprivatekey strumento: blogs.msdn.microsoft.com/dsnotes/2015/08/13/...
Tahir Khalid

3

Stavo ottenendo l'errore: CryptographicException 'Keyset non esiste' quando eseguo l'applicazione MVC.

La soluzione era: dare accesso ai certificati personali all'account con cui è in esecuzione il pool di applicazioni. Nel mio caso è stato aggiungere IIS_IUSRS e la scelta della posizione corretta ha risolto questo problema.

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 risposta di Steve Sheldon ha risolto il problema per me, tuttavia, poiché sto scrivendo le autorizzazioni del certificato senza una GUI, avevo bisogno di una soluzione gestibile da script. Ho faticato a trovare dove era memorizzata la mia chiave privata. La chiave privata non era in -C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys, alla fine ho scoperto che era effettivamente in C:\ProgramData\Microsoft\Crypto\Keys. Di seguito descrivo come l'ho scoperto:

Ho provato FindPrivateKeyma non è stato possibile trovare la chiave privata e usando PowerShell $cert.privatekey.cspkeycontainerinfo.uniquekeycontainernameera null / vuoto.

Fortunatamente, certutil -store myho elencato il certificato e mi ha fornito i dettagli di cui avevo bisogno per scrivere la soluzione.

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

Ho quindi scansionato la c\ProgramData\Microsoft\Crypto\cartella e ho trovato il file 8787033f8ccb5836115b87acb_ca96c65a-4b42-a145-eee62128a in C: \ ProgramData \ Microsoft \ Crypto \ Keys .

Dare accesso in lettura al mio account di servizio a questo file ha risolto i problemi per me


1
L'uso di "certutil -store my" è stata la chiave per risolvere il mio problema. Ho usato il "Nome contenitore univoco" per individuare il file e Sysinternals Process Monitor per risolvere un errore "Accesso negato" sul file del certificato. Nel mio caso ho dovuto fornire l'accesso in lettura al file del certificato per l'utente NT Authority \ IUSR.
hsop

1

Ho trovato alcune informazioni mancanti che mi hanno aiutato a ottenere il mio servizio WCF con sicurezza a livello di messaggio oltre il "Keyset non esiste" che continuavo a eseguire nonostante concedessi le autorizzazioni a tutte le chiavi generate dagli esempi su Internet.

Alla fine ho importato la chiave privata nell'archivio di persone affidabili sul computer locale e quindi ho concesso alla chiave privata le autorizzazioni corrette.

Ciò ha riempito gli spazi vuoti per me e alla fine mi ha permesso di implementare il servizio WCF con sicurezza a livello di messaggio. Sto costruendo un WCF che deve essere conforme a HIPPA.


1

Ho appena reinstallato il mio certificato nel computer locale e quindi funziona correttamente


0

Se usi ApplicationPoolIdentity per il tuo pool di applicazioni, potresti avere problemi con la specifica dell'autorizzazione per quell'utente "virtuale" nell'editor del registro (non esiste tale utente nel sistema).

Quindi, usa subinacl - strumento da riga di comando che abilita gli ACL di registro impostati o qualcosa del genere.


0

Volevo solo aggiungere una risposta di controllo di sanità mentale. Stavo ottenendo lo stesso errore esatto anche dopo aver installato i certificati nei negozi giusti sui miei computer e avendo tutti i giusti privilegi di sicurezza per il client. Ho scoperto che ho confuso il mio certificato cliente e il mio certificato di servizio. Se hai provato tutto quanto sopra, ricontrollerei che tu abbia quei due diritti. Una volta che l'ho fatto, la mia applicazione ha chiamato con successo il servizio web. Ancora una volta, solo un controllo di sanità mentale.


0

Ricevuto questo errore durante l'utilizzo del Fedlet openAM su IIS7

La modifica dell'account utente per il sito Web predefinito ha risolto il problema. Idealmente, vorresti che questo fosse un account di servizio. Forse anche l'account IUSR. Suggerisci di cercare metodi per l'indurimento IIS per inchiodarlo completamente.


0

Ho raggiunto questo risultato nel mio progetto di fabric di servizio dopo che il certificato utilizzato per l'autenticazione con il nostro key vault era scaduto e ruotato, modificando l'impronta digitale. Ho ricevuto questo errore perché mi ero perso ad aggiornare l'impronta digitale nel file applicationManifest.xml in questo blocco che fa esattamente ciò che altre risposte hanno suggerito - a dato il SERVIZIO DI RETE (che tutti i miei ex eseguono come, configurazione standard per il cluster servicefabric azzurro) a accedere alla posizione del negozio di certificati LOCALMACHINE \ MY.

Nota il valore dell'attributo "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

Questa è l'unica soluzione che ha funzionato per me.

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

Riferimento 1

Riferimento 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.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.