Подтвердить что ты не робот

X509Certificate - Keyset не существует

У меня есть приложение WinForms, которое использует WCF и передает в качестве параметра сертификат:

mySvcClient.SendDocument(cert.Export(X509ContentType.SerializedCert, "password"));
...

В службе WCF я восстановил сертификат из массива байтов:

public void SendDocument (byte[] binaryCert)
{   
     X509Certificate2 cert = new X509Certificate2(binaryCert, "password");
...

Но при использовании сертификата для подписи xml я получил ошибку "Keyset не существует":

if (cert.HasPrivateKey) // WORKS!!!
{   
    signedXml.SigningKey = cert.PrivateKey; // THROW "keyset does not exist" EXCEPTION
...

В моем компьютере приложение работает на 100%! Но в WebServer я получил эту ошибку!

Вопрос: даже X509Certificate2 воссоздан из массива байтов, мне нужно специальное разрешение для доступа к закрытому ключу?

Спасибо!

4b9b3361

Ответ 1

Если вы используете Windows Server 2008 или Windows 7, вам необходимо получить доступ к закрытому ключу.

  • используйте инструмент FindPrivateKey для поиска пути. Например:

FindPrivateKey My LocalMachine -n ​​ "CN = MyCert" -a

он возвращает путь: C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys [Имя файла]

  1. Перейдите к этому пути и откройте свойства файла

  2. Перейдите на вкладку безопасности

  3. Нажмите "Изменить", затем "Добавить"

  4. В открывшемся диалоговом окне введите: IIS AppPool\[имя пула приложений] и нажмите OK

Теперь ваш пул приложений имеет разрешение на чтение этого закрытого ключа.

Ответ 2

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

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

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

Ответ 3

Я столкнулся с той же проблемой, и я не знаю как (позор мне), но это сработало:

var certificate = new X509Certificate2(filePath, password,
    X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);

certificate.PrivateKey; // before: error "KeySet does not exist"!

using (certificate.GetRSAPrivateKey()) { } // pure black magic

certificate.PrivateKey; // after: just works! lol

Я надеюсь, что кто-то может ответить на эту загадку.

Ответ 4

Ответ Вано Майсурадзе. Если вы ищете инструмент FindPrivateKey, он включен в файлы Windows Communication Foundation (WCF) и Windows Workflow Foundation (WF) для .NET Framework 4, которые можно найти здесь: http://www.microsoft.com/en-us/download/confirmation.aspx?id=21459

После загрузки и извлечения откройте проект: WF_WCF_Samples\WCF\Setup\FindPrivateKey\CS в Visual Studio и скомпилируйте его. Затем откройте командную строку и перейдите к: WF_WCF_Samples\WCF\Setup\FindPrivateKey\CS\bin

Затем продолжайте отвечать Вано Майсурадзе

Ответ 5

Я думаю, проблема в том, что вам нужно добавить ключ в хранилище сертификатов машины.

Ответ 6

Учетные записи пула приложений не имеют доступа к хранилищу сертификатов по умолчанию.

Либо вы переходите на учетную запись Network Services, как указано Vaibhav.Inspired, или вы предоставляете доступ к сертификату.

Чтобы разрешить доступ, выполните следующую команду:

WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s "IssuedToName" -a "AccountName"

Примечания:

- The tool may need to be installed first. The setup will place the tool at `C:\Program Files (x86)\Windows Resource Kits\Tools\WinHttpCertCfg.exe`.
- `IssuedName` is the issuer property of the certificate that the application will attempt to access
- The command must be run from command prompt with elevated privileges

Ссылка: https://support.microsoft.com/en-us/help/901183/how-to-call-a-web-service-by-using-a-client-certificate-for-authentica Шаг 2

Также вам нужно включить параметр Mark this key as exportable при установке сертификата.