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

157

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

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

При развертывании этот код будет вызываться через службу WCF. Я добавил второй модульный тест, который вызывает службу WCF, однако это не удается с CryptographicExceptionсообщением, "Keyset does not exist"когда я вызываю метод в сторонней веб-службе.

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

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

Ричард Эв
источник

Ответы:

168

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

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

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

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

blowdart
источник
Запуск calcs помог мне в совершенно другой проблеме, спасибо
Джон
3
Я запускаю приложение в качестве администратора, проблема исчезла.
Дерек
1
+1 за документацию MSDN и перечисленные действия применимы даже к веб-приложению
Naren
Добавление "NETWORK SERVICE" к сертификату разрешений безопасности решило это для меня, спасибо!
Опт
276

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

  1. Пуск -> Выполнить -> MMC
  2. Файл -> Добавить / Удалить Snapin
  3. Добавьте оснастку «Сертификаты»
  4. Выберите учетную запись компьютера, затем нажмите «Далее»
  5. Выберите Local Computer (по умолчанию), затем нажмите Finish.
  6. На левой панели из корневого каталога консоли перейдите к Сертификаты (локальный компьютер) -> Личные -> Сертификаты
  7. Ваш сертификат, скорее всего, будет здесь.
  8. Щелкните правой кнопкой мыши свой сертификат -> Все задачи -> Управление личными ключами.
  9. Установите здесь настройки вашего личного ключа.
Стив Шелдон
источник
1
Стоит отметить, что это не вариант на Server 2003, если моя среда не настроена странно. Я могу сделать это на Windows 7, хотя.
Шон Хаббард
что ты имеешь ввиду с установленным приватным ключом здесь ?? Я имею в виду, что вы можете добавить только пользователя с правами доступа !?
mastervv
10
Спасибо, просто хотел отметить, что если вы используете iis7.5 и пул приложений запускается как applicationpoolidentity, вам придется предоставить IIS AppPool \ DefaultAppPool пользовательские разрешения для файла. Это решило проблему для меня.
Ронен Фестингер
25
Я должен был дать разрешение IIS_IUSRS, чтобы заставить его работать на меня.
TrueEddie
1
если вы получаете это во время работы IIS Express, вам нужно дать свои собственные права входа в систему.
Jez
38

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

C: \ Документы и расчеты \ Администратор ...

вместо того

C: \ Документы и расчеты \ Все пользователи ...

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

Желько Танович
источник
Та же проблема. Microsoft должна прекратить позволять агентам по безопасности управлять убежищем.
Пол Стовелл
2
После 3 потерянных часов это решает мою проблему - Спасибо. Я использовал образец FindPrivateKey и был смущен, почему он оказался в хранилище ключей моего пользователя, даже когда он появился в LocalMachine через оснастку MMC.
Роб Поттер
Я бы купил тебе пиво за потраченные часы, возиться с разрешениями, как и любой другой ответ.
Скотт Скоуден
Спасибо Спасибо спасибо! Я потерял около 2,5 часов своей жизни из-за этой ужасной проблемы, и я уверен, что потерял бы 2,5 дня, если бы не увидел этого.
Франк Цанабетис
У меня была та же проблема в обратном порядке. Сначала устанавливается на локальном компьютере, затем в текущем пользователе. Удаление всех сертификатов из обоих магазинов и переустановка под текущим пользователем исправили это.
Барт Verkoeijen
24

Чтобы решить «Keyset не существует» при просмотре из IIS: это может быть для частного разрешения

Чтобы просмотреть и дать разрешение:

  1. Run> ММС> да
  2. нажмите на файл
  3. Нажмите на Добавить / удалить оснастку ...
  4. Двойной клик на сертификате
  5. Учетная запись компьютера
  6. следующий
  7. финиш
  8. Хорошо
  9. Нажмите на сертификаты (локальный компьютер)
  10. Нажмите на Личный
  11. Нажмите Сертификаты

Чтобы дать разрешение:

  1. Щелкните правой кнопкой мыши по названию сертификата.
  2. Все задачи> Управление частными ключами…
  3. Добавить и дать привилегию (добавление IIS_IUSRS и предоставление ему привилегии работает для меня)
Ильяс Хасан Мамун
источник
1
Если вы работаете в пуле приложений, добавьте этого пользователя вместо «IIS AppPool \ DefaultAppPool»
Sameer Alibhai
Это тоже помогло мне. Как только я дал разрешения IIS_IUSRS, он начал работать.
Андрей Мохар
18

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

desegel
источник
11

Я сталкивался с этой проблемой, в моих сертификатах был закрытый ключ, но я получал эту ошибку ( «Набор ключей не существует» )

Причина. Ваш веб-сайт работает под учетной записью «Сетевые службы» или имеет меньше привилегий.

Решение . Измените удостоверение пула приложений на «Локальная система», перезагрузите IIS и проверьте снова. Если он начинает работать, это проблема с привилегиями / меньшими привилегиями, вы можете выдать себя за другого, а затем использовать другие учетные записи.

Vaibhav.Inspired
источник
8

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

остолоп
источник
Я пробовал так много вещей, чтобы решить эту проблему, но этот сделал свое дело!
Гюм Фокс
вау - не ожидал, что это сработает, но это было. Я добавил, IISAPPPool\www.mywebsite.comкакое имя пользователя Windows для моего appool, и это сработало :-)
Simon_Weaver
Кто-нибудь знает, почему это работает? что-то испорчено, потому что это довольно неясно
Simon_Weaver
Не делай этого! Сервер переходит в «плохое состояние», когда сертификаты импортируются и отображаются с типом поставщика «Microsoft Software KSP», когда для папки ..RSA \ MachineKeys изменены базовые разрешения. Более подробная информация reddit.com/r/sysadmin/comments/339ogk/… .
Dhanuka777
3

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

findprivatekey root localmachine -n "CN="CertName" 

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

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

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

C: \ Документы и расчеты \ Все пользователи ..

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

user1773822
источник
2
Привет эта ссылка будет сказать вам , как решить эту проблему , а также найти findprivatekey инструмент: blogs.msdn.microsoft.com/dsnotes/2015/08/13/...
Тахир Халид
3

Я получаю сообщение об ошибке: 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. 
Dev
источник
2

Ответ от Стива Шелдона устранил проблему для меня, однако, поскольку я использую разрешения на сертификаты для сценариев без графического интерфейса, мне нужно было решение с возможностью создания сценариев. Я изо всех сил пытался найти, где хранится мой закрытый ключ. Закрытого ключа не было, в -C:\ProgramData\Microsoft\Crypto\RSA\MachineKeysконце концов я обнаружил, что он был на самом деле C:\ProgramData\Microsoft\Crypto\Keys. Ниже я опишу, как я это узнал:

Я пытался, FindPrivateKeyно он не смог найти закрытый ключ, и с помощью powershell the $cert.privatekey.cspkeycontainerinfo.uniquekeycontainernameбыл пустым / пустым.

К счастью, certutil -store myперечислил сертификат и дал мне детали, необходимые для написания сценария решения.

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

Затем я отсканировал c\ProgramData\Microsoft\Crypto\папку и нашел файл 8787033f8ccb5836115b87acb_ca96c65a-4b42-a145-eee62128a в C: \ ProgramData \ Microsoft \ Crypto \ Keys .

Предоставление моей учетной записи службы доступа к этому файлу устранило проблемы для меня

Дай Бок
источник
1
Использование «certutil -store my» было ключом к решению моей проблемы. Я использовал «Уникальное имя контейнера», чтобы найти файл, и Sysinternals Process Monitor для устранения ошибки «Отказано в доступе» в файле сертификата. В моем случае я должен был предоставить доступ для чтения к файлу сертификата для пользователя NT Authority \ IUSR.
hsop
1

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

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

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

user1483373
источник
1

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

Муни Читтем
источник
0

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

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

Тайгер
источник
0

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

SoftwareSavant
источник
0

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

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

Джефф Миндер
источник
0

Я столкнулся с этим в своем проекте сервисной фабрики после того, как истек срок действия сертификата, который использовался для аутентификации на нашем хранилище ключей, и был повернут, что изменило отпечаток. Я получил эту ошибку, потому что я пропустил обновление отпечатка в файле applicationManifest.xml в этом блоке, который точно выполняет то, что предлагали другие ответы - для предоставления NETWORK SERVICE (как все мои exe-файлы, стандартные конфигурации для кластера Azure Service Fabric) для получить доступ к LOCALMACHINE \ MY сертификату местоположение магазина.

Обратите внимание на значение атрибута «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

Это единственное решение, сработавшее для меня.

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

Ссылка 1

Ссылка 2

CharithJ
источник
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
источник