Почему я получаю Cryptography_CSP_NoPrivateKey при использовании IIS, но не при использовании сервера разработки VS? - PullRequest
2 голосов
/ 25 марта 2009

Я делаю веб-приложение, которое использует внешний веб-сервис. Этот внешний веб-сервис требует от меня подписи каждого из моих запросов. Поэтому я использую класс WebServicesClientProtocol и .NET 2.0, сначала используя внешний веб-сервис, а затем вручную отредактируйте файл Reference.cs и измените расширенный класс с System.Web.Services.Protocols.SoapHttpClientProtocol на Microsoft.Web.Services2.WebServicesClientProtocol. Тогда в методе Page_Load у меня есть следующий код:

try
{
    // Create the ws endpoint
    var uriServiceAddress = new Uri("urn:something-wse:something_NNNN");
    var uribuilderViaRouter = new UriBuilder("http://xx.xxx.xx/SrvXXX_NNNN/Test.asmx");
    var endpointReference = new EndpointReference(uriServiceAddress, uribuilderViaRouter.Uri);

    // Create the ws client
    var client = (WebServicesClientProtocol) new Test.Something();
    client.Destination = endpointReference;

    // Read the certificate from MyStore on LocalMachine
    X509CertificateStore localStore = X509CertificateStore.LocalMachineStore(X509CertificateStore.MyStore);
    X509SecurityToken securityToken = null;
    if (!localStore.OpenRead()) throw new Exception("Unable to open localstore for read");
    X509CertificateCollection certificateCollection = localStore.FindCertificateBySubjectString("email@subject.test");
    if (certificateCollection.Count == 0) throw new Exception("Unable to obtain security token.");
    securityToken = new X509SecurityToken(certificateCollection[0]);
    localStore.Close();

    // Attach the security toekn to the client request
    client.RequestSoapContext.Security.Tokens.Add(securityToken);
    client.RequestSoapContext.Security.Elements.Add(new MessageSignature(securityToken));

    // Set the timeouts
    client.RequestSoapContext.Security.Timestamp.TtlInSeconds = 2 * 60;
    client.Timeout = 60 * 10 * 1000;    // 10 mínútur ættu að duga í flest.

    // Call the test function
    DataSet set = ((Test.Something)client).searchMethod("Parameter 1", "Parameter 2");
    Label1.Text = User.Identity.Name+ " worked! " + set.Tables.Count + " tables!";
}
catch (Exception exc)
{
    Label1.Text = User.Identity.Name + " exception: " + exc.ToString();
}

Это прекрасно работает, когда я запускаю его с помощью Visual Studio Development Server, но когда я перехожу на IIS, он перестает работать, и я получаю ужасное исключение Cryptography_CSP_NoPrivateKey.

1) Я уже прочитал сертификат должным образом в LocalMachine / MyStore с помощью MMC, а затем я изменил разрешения на закрытый ключ с помощью WSE 2.0 SP3, чтобы у всех был полный доступ к нему. Вы можете увидеть это здесь:

альтернативный текст http://www1.ruedenet.is/files/CertError1.png

2) Я также установил свойство так, чтобы при отладке приложения использовался сервер разработки Visual Studio:

альтернативный текст http://www1.ruedenet.is/files/CertError2.png

3) Затем я запускаю его и получаю хороший результат:

альтернативный текст http://www1.ruedenet.is/files/CertError3.png

4) Однако, когда я изменяю свойство для использования IIS (и VS создает виртуальный каталог) следующим образом:

альтернативный текст http://www1.ruedenet.is/files/CertError4.png

5) Я также изменяю метод аутентификации в IIS, чтобы войти в систему (на самом деле нет причин для этого):

альтернативный текст http://www1.ruedenet.is/files/CertError5.png

6) Поэтому меня просят войти в Windows:

альтернативный текст http://www1.ruedenet.is/files/CertError6.png

7) А потом моя страница запускается и выдает ошибку:

альтернативный текст http://www1.ruedenet.is/files/CertError7.png

Если бы вы могли помочь мне с этим, я, безусловно, был бы признателен. Я уже потратил на это часы и не хочу тратить больше времени, если я делаю фундаментальную ошибку, которую вы, ребята, видите. Кстати, я разрабатываю с использованием Visual Studio 2008 на Windows Server 2008 с отключенным UAC: -)

Очень жду ответа от вас, ребята. Спасибо.

1 Ответ

2 голосов
/ 25 марта 2009

: -)

Я решил эту проблему в несколько шагов:

1) Я сменил пользователя Default Application Pool на свое имя пользователя ...

альтернативный текст http://www1.ruedenet.is/files/ErrorFix1.png

... и это сработало. Я изменил пользователя пула приложений обратно на NETWORK SERVICE, и он снова не работал. Это говорит мне о том, что проблема связана с пользователем NETWORK SERVICE. Поэтому я вернулся к поиску проблем с разрешениями этого пользователя.

2) При просмотре и чтении Интернета я обнаружил блог-пост Тима Джейкобса Сертификат App-V 4.5 в изобилии в http://timjacobs.blogspot.com/2008/11/app-v-45-certificate-galore.html. Ну, ничего нового не было в нем до конца, где он говорит о месте хранения закрытого ключа на диске. Итак, я запустил инструмент FindPrivateKey.exe , ...

C: \ MyTools> FindPrivateKey.exe My LocalMachine -t "8c 1a e6 1b 6d f2 f8 18 c8 26 b6 fa cd 60 fd 94 c7 a1 96 58"
Каталог закрытых ключей:
C: \ Users \ alfred \ AppData \ Roaming \ Microsoft \ Crypto \ RSA \ S-1-5-21-3612370315-2559787 071-3412320394-1135
Имя файла закрытого ключа:
b3765d4123902371ea91c5c9a521932e_96ce3a90-5634-44e6-8aa2-acb123b8b3bf

... который говорит мне, что местоположение закрытого ключа находится в каталоге C:\Users\alfred\..., и пользователь NETWORK SERVICE, вероятно, не имеет доступа к этому каталогу !!!

3) Поэтому я последовал предложению Тима использовать MMC для экспорта сертификата и закрытого ключа из Local Computer/Personal/Certificates и затем импортировать его в Local Computer/Trusted Root Certificate Authorities/Certificates. После экспорта FindPrivateKey.exe сообщил, ...

C: \ MyTools> FindPrivateKey.exe My LocalMachine -t "8c 1a e6 1b 7d f1 f8 18 c8 26 b6 fa cd 60 fd 94 c7 a1 96 58"
Ошибка FindPrivateKey по следующей причине: в магазине не найдено сертификатов с ключом '8c 1a e6 1b 7d f1 f8 18 c8 26 b6 fa cd 60 fd 94 c7 a1 96 58'.

... который говорит мне, что экспорт работал. После импорта и копирования вставьте его обратно в Local Computer/Personal/Certificates Я получаю ...

C: \ MyTools> FindPrivateKey.exe My LocalMachine -t "8c 1a e6 1b 7d f1 f8 18 c8 26 b6 fa cd 60 fd 94 c7 a1 96 58"
Каталог закрытых ключей:
C: \ ProgramData \ Microsoft \ Crypto \ RSA \ MachineKeys
Имя файла закрытого ключа:
b3765d4d5a902371ea91c5c9a521932e_96ce3a90-5634-44e6-8aa2-acbaccb8b3bf

... и теперь закрытый ключ находится в публичном месте, в каталоге C:\ProgramData\.... Затем я изменил разрешения для личного ключа пользователя NETWORK SERVICE на Полный доступ , используя X509 Certificate Tool , как я делал раньше.

И теперь это работает !!!

Я просто не могу отблагодарить вас за ваш пост, Тим. Спасибо.

...