CryptographicException "Набор ключей не существует", но только через WCF
Вопрос
У меня есть некоторый код, который вызывает сторонний веб-сервис, защищенный с помощью сертификации X.509.
Если я вызываю код напрямую (используя модульный тест), он работает без каких-либо проблем.
При развертывании этот код будет вызываться через службу WCF.Я добавил второй модульный тест, который вызывает службу WCF, однако это приводит к сбою из-за CryptographicException
, сообщение "Keyset does not exist"
когда я вызываю метод в стороннем веб-сервисе.
Я предполагаю, что это связано с тем, что моя служба WCF будет пытаться вызвать стороннюю веб-службу, используя другого пользователя.
Кто-нибудь может пролить дополнительный свет на этот вопрос?
Решение
Вероятно, это будет проблема с разрешениями в сертификате.
При запуске модульного теста вы собираетесь выполнять их в вашем собственном пользовательском контексте, который (в зависимости от того, в каком хранилище клиент сертификат включен) будет иметь доступ к закрытому ключу этого сертификата.
Однако, если ваша служба WCF размещена в IIS или как служба Windows, скорее всего, она будет запущена под учетной записью службы (Сетевая служба, локальная служба или какая-либо другая учетная запись с ограниченным доступом).
Вам нужно будет установить соответствующие разрешения для закрытого ключа, чтобы разрешить этой учетной записи службы доступ к нему.MSDN имеет подробности
Другие советы
Скорее всего, это связано с тем, что пользователь IIS не имеет доступа к закрытому ключу вашего сертификата.Вы можете установить это, выполнив следующие действия...
- Пуск -> Выполнить -> MMC
- Файл -> Добавить / Удалить оснастку
- Добавьте оснастку Сертификаты
- Выберите Учетная запись компьютера, затем нажмите Далее
- Выберите Локальный компьютер (по умолчанию), затем нажмите кнопку Готово
- На левой панели из корня консоли перейдите в раздел Сертификаты (локальный компьютер) -> Личные -> Сертификаты
- Ваш сертификат, скорее всего, будет здесь.
- Щелкните правой кнопкой мыши на вашем сертификате -> Все задачи -> Управление закрытыми ключами
- Установите настройки вашего закрытого ключа здесь.
Прошлой ночью у меня была аналогичная проблема.Разрешения для закрытого ключа были установлены правильно, все, по-видимому, было в порядке, за исключением ошибки Keyset doesn't exist.В итоге оказалось, что сертификат был сначала импортирован в хранилище текущего пользователя, а затем перемещен в хранилище локального компьютера.Однако это не привело к перемещению закрытого ключа, который все еще находился в
C:\Documents и настройки\Администратор...
вместо того, чтобы
C:\Documents и настройки\Для всех пользователей...
Несмотря на то, что разрешения для ключа были установлены правильно, ASPNET не смог получить к нему доступ.Когда мы повторно импортировали сертификат, чтобы закрытый ключ был помещен в ветку "Все пользователи", проблема исчезла.
Чтобы решить проблему “Набор ключей не существует” при просмотре из IIS: Это может быть сделано с личного разрешения
Просмотреть и дать разрешение:
- Выполнить> mmc> да
- нажмите на файл
- Нажмите на кнопку Добавить / удалить оснастку…
- Дважды щелкните по сертификату
- Учетная запись компьютера
- Далее
- Финиш
- ОК
- Нажмите на Сертификаты (Локальный компьютер).
- Нажмите на Личный
- Щелкните Сертификаты
Чтобы дать разрешение:
- Щелкните правой кнопкой мыши на названии сертификата
- Все задачи> Управление закрытыми ключами…
- Добавьте и предоставьте привилегию (добавление IIS_IUSRS и предоставление ему привилегии работает для меня)
Возникла та же проблема при попытке запустить приложение WCF из Visual Studio.Решил эту проблему, запустив Visual Studio от имени администратора.
Я столкнулся с этой проблемой, мои сертификаты имели закрытый ключ, но я получал эту ошибку("Набор ключей не существует")
Потому что: Ваш веб-сайт работает под учетной записью "Сетевые службы" или с меньшими привилегиями.
Решение:Измените идентификатор пула приложений на "Локальная система", сбросьте IIS и проверьте еще раз.Если он начнет работать, это проблема с разрешениями / меньшими привилегиями, вы можете выдавать себя за другого пользователя, используя другие учетные записи.
Совершенно разочаровывающий, у меня была та же проблема, и я перепробовал большую часть из вышеперечисленных.Экспортированный сертификат корректно имел разрешения на чтение файла в C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
, однако, как оказалось, у него не было разрешения на доступ к папке.Добавил его, и это сработало
У меня тоже точно такая же проблема.Я использовал эту команду
findprivatekey root localmachine -n "CN="CertName"
результат показывает, что закрытый ключ находится в c:\ProgramData папке вместо C:\Documents и настроек\Для всех пользователей..
Когда я удаляю ключ из c:\ProgramData папки, снова запустить команду FindPrivateKey не удается.т.е.он не находит ключ.
Но если я буду искать тот же ключ, возвращенный предыдущей командой, я все равно смогу найти ключ в
C:\Documents и настройки\Для всех пользователей..
Итак, насколько я понимаю, IIS или размещенный WCF не находят закрытый ключ от C:\Documents и настроек\Всех пользователей..
Я получал сообщение об ошибке :CryptographicException "Набор ключей не существует", когда я запускаю приложение 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 для своего пула приложений, у вас может возникнуть проблема с указанием прав доступа для этого "виртуального" пользователя в редакторе реестра (в системе такого пользователя нет).
Итак, используйте субинакл - инструмент командной строки, который позволяет устанавливать ACL реестра или что-то вроде этого.
Я просто хотел добавить ответ на проверку здравомыслия.Я получал точно такую же ошибку даже после установки сертификатов в нужные хранилища на своих компьютерах и получения всех необходимых привилегий безопасности для клиента.Оказывается, я перепутал свой ClientCertificate и Сервисный сертификат.Если вы перепробовали все вышеперечисленное, я бы еще раз проверил, что у вас есть эти два варианта.Как только я это сделал, мое приложение успешно вызвало веб-службу.Опять же, просто проверка на вменяемость.
Получил эту ошибку при использовании OpenAM Fedlet на IIS7
Изменение учетной записи пользователя для веб-сайта по умолчанию решило проблему.В идеале вы хотели бы, чтобы это была учетная запись службы.Возможно, даже учетная запись IUSR.Предложите поискать методы упрочнения IIS, чтобы полностью закрепить его.
Я нажал на это в своем проекте service fabric после того, как срок действия сертификата, используемого для аутентификации в нашем хранилище ключей, истек и был повернут, что изменило отпечаток большого пальца.Я получил эту ошибку, потому что я пропустил обновление отпечатка большого пальца в applicationManifest.xml файл в этом блоке, который точно выполняет то, что предлагали другие ответы - для предоставления СЕТЕВОЙ СЛУЖБЕ (с которой работают все мои бывшие, стандартная конфигурация для кластера 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 -->
Я просто переустановил свой сертификат на локальном компьютере, и после этого он работает нормально