CryptographicException 'Keyset não existe', mas apenas através do WCF

157

Eu tenho algum código que faz uma chamada para um serviço da web de terceiros protegido com a certificação X.509.

Se eu ligar diretamente para o código (usando um teste de unidade), ele funcionará sem problemas.

Quando implantado, esse código será chamado por meio de um serviço WCF. Adicionei um segundo teste de unidade que chama o Serviço WCF, mas isso falha com uma CryptographicExceptionmensagem "Keyset does not exist"quando chamo um método no serviço Web de terceiros.

Presumo que isso ocorra porque meu Serviço WCF tentará chamar o serviço Web de terceiros usando um usuário diferente para mim.

Alguém pode lançar alguma luz adicional sobre esse assunto?

Richard Ev
fonte

Respostas:

168

Provavelmente será um problema de permissão no certificado.

Ao executar um teste de unidade, você os executará no seu próprio contexto de usuário, que (dependendo do armazenamento do certificado de cliente ) terá acesso à chave privada desse certificado.

No entanto, se o seu serviço WCF estiver hospedado no IIS ou como um serviço do Windows, provavelmente ele estará sendo executado em uma conta de serviço (Serviço de Rede, Serviço Local ou outra conta restrita).

Você precisará definir as permissões apropriadas na chave privada para permitir o acesso dessa conta de serviço a ela. MSDN tem os detalhes

blowdart
fonte
Calcs correndo me ajudou durante completamente diferentes problema graças
John
3
Eu corro meu aplicativo como administrador, o problema desapareceu.
Derek
1
+1 para a documentação MSDN e os passos listados aplica até mesmo para uma aplicação Web
Naren
Adicionar "SERVIÇO DE REDE" às permissões de segurança do certificado resolveu isso para mim, obrigado!
OpMt 5/06
276

Isso é mais provável porque o usuário do IIS não tem acesso à chave privada do seu certificado. Você pode definir isso seguindo estas etapas ...

  1. Iniciar -> Executar -> MMC
  2. Arquivo -> Adicionar / Remover Snapin
  3. Adicionar o snap-in de certificados
  4. Selecione Conta de computador e clique em Avançar.
  5. Selecione Computador local (o padrão) e clique em Concluir
  6. No painel esquerdo da Raiz do console, navegue para Certificados (Computador local) -> Pessoal -> Certificados
  7. Seu certificado provavelmente estará aqui.
  8. Clique com o botão direito do mouse no seu certificado -> Todas as tarefas -> Gerenciar chaves privadas
  9. Defina suas configurações de chave privada aqui.
Steve Sheldon
fonte
1
Vale ressaltar que essa não é uma opção no Server 2003, a menos que meu ambiente esteja configurado maluco. Eu posso fazer isso no Windows 7.
Shawn Hubbard
o que você quer dizer com definir chave privada aqui? Quero dizer, você só pode adicionar o usuário com acesso certo !?
Mastervv 15/05
10
Obrigado, gostaria apenas de salientar que, se você usar o iis7.5 e o pool de aplicativos for executado como uma validade de aplicativo, precisará conceder permissões de usuário do IIS AppPool \ DefaultAppPool ao arquivo. Isso corrigiu o problema para mim.
Ronen Festinger
25
Eu tive que dar permissão ao IIS_IUSRS para que funcionasse para mim.
TrueEddie
1
se você estiver obtendo isso enquanto executa o IIS express, precisará conceder suas próprias permissões de login.
Jez
38

Eu tive um problema idêntico ontem à noite. As permissões na chave privada foram definidas corretamente, tudo estava aparentemente bom, exceto o erro Keyset não existe. No final, descobriu-se que o certificado foi importado para o repositório de usuários atual primeiro e depois movido para o repositório de máquinas local. No entanto - isso não moveu a chave privada, que ainda estava no

C: \ Documentos e configurações \ Administrador ...

ao invés de

C: \ Documentos e configurações \ Todos os usuários ...

Embora as permissões na chave tenham sido definidas corretamente, o ASPNET não pôde acessá-lo. Quando reimportamos o certificado para que a chave privada seja colocada na ramificação Todos os usuários, o problema desapareceu.

Željko Tanović
fonte
Mesmo problema. A Microsoft precisa parar de deixar que os bozos de segurança executem o asilo.
Paul Stovell
2
Após 3 horas perdidas, isso resolve meu problema - Obrigado. Usei o exemplo FindPrivateKey e fiquei confuso por que parecia estar no keystore do meu usuário, mesmo quando apareceu no LocalMachine por meio do snap-in do MMC.
Rob Potter
Eu compraria uma cerveja para você por horas perdidas mexendo com permissões, como todas as outras respostas me disseram.
Scott Scowden
Obrigado, obrigado, obrigado! Perdi cerca de 2,5 horas da minha vida graças a esse problema horrível e tenho certeza de que teria perdido 2,5 dias se não visse isso.
Frank Tzanabetis
Eu tive o mesmo problema ao contrário. Instalado primeiro na máquina local e depois no usuário atual. A remoção de todos os certificados de ambas as lojas e a reinstalação em Usuário atual foram corrigidas.
Bart Verkoeijen
24

Para resolver o "Conjunto de chaves não existe" ao navegar no IIS: Pode ser para permissão privada

Para visualizar e conceder a permissão:

  1. Execute> mmc> yes
  2. clique no arquivo
  3. Clique em Adicionar / remover snap-in…
  4. Clique duas vezes no certificado
  5. Conta de Computador
  6. Próximo
  7. Terminar
  8. Está bem
  9. Clique em Certificados (Computador Local)
  10. Clique em Pessoal
  11. Clique em Certificados

Para dar a permissão:

  1. Clique com o botão direito do mouse no nome do certificado
  2. Todas as tarefas> Gerenciar chaves privadas…
  3. Adicionar e conceder o privilégio (adicionar IIS_IUSRS e conceder o privilégio funciona para mim)
Mestre Ilyas Hasan Mamun
fonte
1
Se você estiver executando em um pool de aplicativos, adicione este usuário "IIS AppPool \ DefaultAppPool"
Sameer Alibhai 22/17/17
Isso também me ajudou. Assim que dei as permissões ao IIS_IUSRS, ele começou a funcionar.
Andrej Mohar
18

Teve o mesmo problema ao tentar executar o aplicativo WCF no Visual Studio. Resolvido, executando o Visual Studio como administrador.

desegel
fonte
11

Eu enfrentei esse problema, meus certificados estavam com chave privada, mas estava recebendo esse erro ( "O conjunto de chaves não existe" )

Causa: seu site está sendo executado na conta "Serviços de rede" ou com menos privilégios.

Solução : altere a identidade do pool de aplicativos para "Sistema local", redefina o IIS e verifique novamente. Se começar a funcionar, é um problema de permissão / menos privilégios, você também pode se passar por outras contas.

Vaibhav.Inspired
fonte
8

Totalmente frustrante, tive o mesmo problema e tentei a maioria dos itens acima. O certificado exportado corretamente tinha permissões para ler o arquivo C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys, no entanto, como se vê, ele não tinha permissão na pasta. Adicionado e funcionou

vira-lata
fonte
Eu tentei muitas coisas para resolver esse problema, mas este fez o truque!
Gyum Fox
uau - não estava esperando que funcionasse, mas funcionou. Acrescentei IISAPPPool\www.mywebsite.comque é as janelas nome de usuário para o meu appool e funcionou :-)
Simon_Weaver
Alguém sabe por que isso funciona? é algo corrompido, porque isso é muito obscura
Simon_Weaver
Não faça isso! O servidor entra no "estado ruim" em que os certificados estão sendo importados e exibidos com o tipo de provedor "Microsoft Software KSP" quando a pasta ..RSA \ MachineKeys tem suas permissões básicas alteradas. Mais detalhes reddit.com/r/sysadmin/comments/339ogk/… .
precisa saber é o seguinte
3

Eu tenho um problema exatamente semelhante também. Eu usei o comando

findprivatekey root localmachine -n "CN="CertName" 

o resultado mostra que a chave privada está na pasta c: \ ProgramData em vez de C: \ Documents and settngs \ All users ..

Quando eu excluo a chave da pasta c: \ ProgramData, execute novamente o comando findPrivatekey. ie não encontra a chave.

Mas se eu procurar a mesma chave retornada pelo comando anterior, ainda posso encontrar a chave em

C: \ Documentos e configurações \ Todos os usuários ..

Pelo que entendi, o IIS ou o WCF hospedado não está encontrando a chave privada em C: \ Documents and settngs \ All users ..

user1773822
fonte
2
Olá, este link mostrará como resolver esse problema e também localize a ferramenta findprivatekey : blogs.msdn.microsoft.com/dsnotes/2015/08/13/…
Tahir Khalid
3

Eu estava recebendo o erro: CryptographicException 'Keyset is not exist' quando executo o aplicativo MVC.

A solução foi: conceder acesso aos certificados pessoais à conta em que o pool de aplicativos está sendo executado. No meu caso, foi adicionar o IIS_IUSRS e escolher o local certo resolveu esse 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. 
Dev
fonte
2

A resposta de Steve Sheldon corrigiu o problema para mim, no entanto, como estou criando scripts de permissões de certificado sem uma GUI, precisava de uma solução com script. Eu lutei para descobrir onde minha chave privada estava armazenada. A chave privada não estava inserida -C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys; eventualmente, descobri que estava realmente inserida C:\ProgramData\Microsoft\Crypto\Keys. Abaixo, descrevo como descobri isso:

Eu tentei, FindPrivateKeymas não foi possível encontrar a chave privada e, usando o PowerShell, o valor $cert.privatekey.cspkeycontainerinfo.uniquekeycontainernameera nulo / vazio.

Felizmente, certutil -store mylistei o certificado e me deu os detalhes necessários para criar o script da solução.

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

Em seguida, verifiqueic\ProgramData\Microsoft\Crypto\ a pasta e localizei o arquivo 8787033f8ccb5836115b87acb_ca96c65a-4b42-a145-eee62128a em C: \ ProgramData \ Microsoft \ Crypto \ Keys .

Ao fornecer acesso de leitura à minha conta de serviço, esse arquivo corrigiu os problemas para mim

Dai Bok
fonte
1
Usar "certutil -store my" foi a chave para resolver o meu problema. Usei o "Nome exclusivo do contêiner" para localizar o arquivo e o Sysinternals Process Monitor para solucionar um erro "Acesso negado" no arquivo de certificado. No meu caso, tive que fornecer acesso de leitura ao arquivo de certificado para o usuário NT Authority \ IUSR.
hsop
1

Encontrei algumas informações ausentes que me ajudaram a obter meu serviço WCF com segurança no nível de mensagem além do "Conjunto de chaves não existe" em que eu continuava encontrando, apesar de conceder permissões para todas as chaves geradas nos exemplos na Internet.

Finalmente, importei a chave privada para o armazenamento de pessoas confiáveis ​​na máquina local e, em seguida, concedi à chave privada as permissões corretas.

Isso preencheu os espaços em branco para mim e finalmente me permitiu implementar o serviço WCF com segurança no nível de mensagem. Estou construindo um WCF que deve ser compatível com HIPPA.

user1483373
fonte
1

Acabei de reinstalar meu certificado na máquina local e ele está funcionando bem

Muni Chittem
fonte
0

Se você usar ApplicationPoolIdentity para seu pool de aplicativos, poderá ter problemas ao especificar a permissão para esse usuário "virtual" no editor de registro (não existe esse usuário no sistema).

Portanto, use subinacl - ferramenta de linha de comando que permite definir ACLs de registro ou algo assim.

tyger
fonte
0

Eu só queria adicionar uma resposta de verificação de sanidade. Eu estava recebendo o mesmo erro mesmo depois de instalar os certificados nos armazenamentos certos nas minhas máquinas e ter todos os privilégios de segurança certos para o cliente. Acontece que eu misturei meu clientCertificate e meu certificado de serviço. Se você tentou todas as opções acima, eu checaria duas vezes se você tem essas duas retas. Depois disso, meu aplicativo chamou com êxito o serviço da web. Mais uma vez, apenas um verificador de sanidade.

SoftwareSavant
fonte
0

Recebeu este erro ao usar o FedAM openAM no IIS7

Alterar a conta do usuário para o site padrão resolveu o problema. Idealmente, você deseja que essa seja uma conta de serviço. Talvez até a conta IUSR. Sugira a pesquisa de métodos para o fortalecimento do IIS, para corrigir completamente.

Jeff Minder
fonte
0

Eu bati isso no meu projeto de malha de serviço depois que o certificado usado para autenticação contra nosso cofre de chaves expirou e foi rotacionado, o que alterou a impressão digital. Eu recebi esse erro porque perdi a atualização da impressão digital no arquivo applicationManifest.xml neste bloco, que faz exatamente o que outras respostas sugeriram - para obter permissões de NETWORK SERVICE (que todos os meus exs executam como, configuração padrão para o cluster azul do servicefabric) acesse o local da loja de certificados LOCALMACHINE \ MY.

Observe o valor do atributo "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 -->

Sáb Thiru
fonte
0

Esta é a única solução que funcionou para mim.

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

Referência 1

Referência 2

CharithJ
fonte
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
fonte