CryptographicException "набор ключей не существует", но только через WCF

у меня есть код, который вызывает стороннюю веб-службу, защищенную с помощью сертификации X. 509.

Если я вызываю код напрямую (используя модульный тест), он работает без каких-либо проблем.

при развертывании этот код будет вызываться через службу WCF. Я добавил второй модульный тест, который вызывает службу WCF, однако это не удается с CryptographicException, когда я вызываю метод веб-сервиса третьей стороны.

Я предполагаю, что это потому что моя служба WCF будет пытаться вызвать стороннюю веб-службу, используя другого пользователя для себя.

кто-нибудь может пролить дополнительный свет на этот вопрос?

15 ответов


вероятно, это будет проблема с разрешениями на сертификат.

при запуске модульного теста вы будете выполнять их в своем собственном пользовательском контексте ,который (в зависимости от того, какой магазин клиент сертификат в) будет иметь доступ к закрытому ключу этого сертификата.

однако, если ваша служба WCF размещена в IIS или в качестве службы Windows, скорее всего, она будет работать под учетной записью службы (сетевая служба, локальная служба или какая-либо другая ограниченная учетная запись).

вам нужно будет установить соответствующие разрешения на закрытый ключ, чтобы разрешить этой учетной записи службы доступ к нему. В MSDN подробности


Это скорее всего потому, что пользователь IIS не имеет доступа к закрытому ключу сертификата. Вы можете установить это, выполнив следующие действия...

  1. Пуск - > Выполнить - > MMC
  2. Файл - > Добавить / Удалить Snapin
  3. добавить привязку сертификатов в
  4. выберите учетную запись компьютера, затем нажмите кнопку Далее
  5. выберите локальный компьютер (по умолчанию), затем нажмите кнопку Готово
  6. на левой панели от корня консоли, перейдите к Сертификаты (Локальный Компьютер) - > Личный - > Сертификаты
  7. Ваш сертификат, скорее всего, будет здесь.
  8. щелкните правой кнопкой мыши на сертификате -> все задачи - > Управление закрытыми ключами
  9. установите настройки закрытого ключа здесь.

Я вчера идентичный вопрос. Разрешения на закрытый ключ были установлены правильно, все было, по-видимому, хорошо, кроме набора ключей не существует ошибки. В итоге оказалось, что сертификат сначала импортировался в хранилище текущего пользователя, а затем перемещался в хранилище локального компьютера. Однако-это не переместило закрытый ключ, который все еще был в

C:\Documents и settngs\администратор...

вместо

C:\Documents и settngs\все пользователи...

Altough разрешения на ключ были установлены правильно, ASPNET не мог получить к нему доступ. Когда мы повторно импортировали сертификат, чтобы закрытый ключ был помещен в ветку все пользователи, проблема исчезла.


чтобы решить "набор ключей не существует" при просмотре из IIS: это может быть для частного разрешения

для просмотра и предоставления разрешения:

  1. выполнить>mmc>да
  2. выберите файл
  3. Нажмите кнопку Добавить / удалить оснастку...
  4. дважды щелкните сертификат
  5. Учетная Запись Компьютера
  6. далее
  7. готово
  8. Ok
  9. клик на сертификатах (локальный компьютер)
  10. нажмите на Personal
  11. Щелкните Сертификаты

дать разрешение:

  1. щелкните правой кнопкой мыши на имени сертификата
  2. Все Задачи>Управление Закрытыми Ключами...
  3. добавить и дать привилегию (добавление IIS_IUSRS и предоставление ему привилегии работает для меня )

была та же проблема при попытке запустить приложение WCF из Visual Studio. Решил ее запустив Visual Studio в качестве администратора.


Я столкнулся с этой проблемой, мои сертификаты, где есть закрытый ключ, но я получал эту ошибку ( "Keyset не существует")

причина: ваш веб-сайт работает под учетной записью "сетевые службы" или имеет меньше привилегий.

решение: измените идентификатор пула приложений на "локальная система", сбросьте IIS и проверьте еще раз. Если он начинает работать, это проблема разрешения/меньше привилегий, вы можете олицетворять, а затем использовать другие учетные записи тоже.


полностью расстраивает, у меня была та же проблема и попробовал большую часть выше. Экспортированный сертификат правильно имел разрешения на чтение файла в C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys, однако, как оказалось, у него не было разрешения на папку. Добавил его, и это сработало


У меня точно такая же проблема. Я использовал команду

findprivatekey root localmachine -n "CN="CertName" 

результат показывает, что закрытый ключ находится в c:\ProgramData папка вместо C:\Documents и settngs\все пользователи..

когда я удаляю ключ из c:\ProgramData папка, снова запустить команду findPrivatekey не удается. то есть. не находит ключ.

но если я ищу тот же ключ, возвращенный предыдущей командой, я все еще могу найти ключ в

C:\Documents и settngs\все пользователи..

поэтому, насколько я понимаю, IIS или размещенный WCF не находит закрытый ключ из C:\Documents и settngs\все пользователи..


Я получал ошибку: CryptographicException "Keyset не существует" при запуске приложения MVC.

решение: предоставить доступ к личным сертификатам учетной записи, под которой работает пул приложений. В моем случае это было добавить IIS_IUSRS и выбор правильного местоположения решил эту проблему.

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. 

Я нашел некоторую недостающую информацию, которая помогла мне получить мою службу WCF с безопасностью уровня сообщений мимо "набора ключей не существует", с которым я продолжал работать, несмотря на предоставление разрешений на все ключи, созданные из примеров в интернете.

Я, наконец, импортировал закрытый ключ в хранилище доверенных людей на локальном компьютере, а затем предоставил закрытому ключу правильные разрешения.

Это заполнило пробелы для меня и, наконец, позволило мне реализовать служба WCF с безопасностью уровня сообщений. Я создаю WCF, который должен быть совместим с HIPPA.


Если вы используете ApplicationPoolIdentity для своего пула приложений, у вас может возникнуть проблема с указанием разрешения для этого "виртуального" пользователя в редакторе реестра (такого Пользователя в системе нет).

используйте программы SubInACL - инструмент командной строки, который позволяет установить ACL реестра, или что-то вроде этого.


Я просто хотел добавить ответ проверки здравомыслия. Я получал ту же самую ошибку даже после установки сертификатов в правильные магазины на моих машинах и имел все права безопасности для клиента. Оказывается, я перепутал сертификат клиента и сертификат службы. Если вы пробовали все вышеперечисленное, я бы дважды проверил, что у вас есть эти два прямо. Как только я это сделал, мое приложение успешно вызвало веб-службу. Опять же, просто проверка здравомыслия.


получил эту ошибку при использовании Федлета openAM на IIS7

изменение учетной записи пользователя для веб-сайта по умолчанию решило проблему. В идеале, вы бы хотели, чтобы это была учетная запись службы. Возможно, даже счет IUSR. Предложите поиск методов упрочнения IIS, чтобы полностью прибить его.


Я ударил это в моем проекте service fabric после того, как сертификат, используемый для аутентификации против нашего хранилища ключей, истек и был повернут, что изменило отпечаток пальца. Я получил эту ошибку, потому что я пропустил обновление отпечатка пальца в applicationManifest.xml-файл в этом блоке, который точно выполняет то, что предложили другие ответы - для данной сетевой службы (все мои exes работают как стандартная конфигурация для кластера Azure servicefabric) разрешения на доступ к LOCALMACHINE\MY CERT store местоположение.

отметить "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 -->

Я просто переустановил свой сертификат на локальном компьютере, а затем он работает нормально