25.06.2002 14:24:32Web-сервисы, КриптоПро TLS и .NET клиент Ответов: 3
Valentin
Решил использовать PKI для организации защиты корпоративной интернет службы (системы клиент-банк), выполненной в виде Web-сервиса.
Установил КриптоПро CSP и TLS на сервер и клиента. На сервере (W2K SP2)установлен IIS и CA.
IIS обеспечивает доступ клиентам к моему Web-сервису через https.
Настроил 2-х стороннее SSL соединение (с аунетнификацией клиента и сервера) на сгенерированных вашим CSP сертификатах. Ключи для сервера храню в реестре, для клеента - на дискете. Подключаюсь Internet Explorer’ом все работает: IE запрашивает пароль для доступа к ключевому насителю и IIS пускает меня и дает выполнить методы web-сервиса. Подключаюсь используя MSSOAP.SoapClient:

Set cb = CreateObject("MSSOAP.SoapClient")
cb.mssoapinit "https://dev/WebServices/ClientBank/ClientBank.asmx?WSDL"
cb.ConnectorProperty("SSLClientCertificateName") = "Valentin"
Dim Str As String
Str = cb.GetTestInfo()
(предварительно утановив сертификат в персональное хранилище сертификатов). Все работает.
Создаю консольное приложение на C# в VS .NET, добавляю Web Reference на мой Web-сервис, и вызываю его метод примерно так:
X509Certificate X509Certificate sert = X509Certificate.CreateFromCertFile("D:\\Valentin.cer");
ClientBank cl = new ClientBank();
cl.ClientCertificates.Add(sert);
String strTestInfo = cl.GetTestInfo();
где D:\Valentin.cer - экспортированный сертификат из персонального хранилища. Если использую ваш CSP и TLS (на сервере и клиенте), то при вызове GetTestInfo() возникает следующее исключение:
"Unhandled Exception: System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send.
at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest
request)
at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at ConsoleApplication1.dev.ClientBank.GetTestInfo() in d:\net\client\consoleapplication1\web references\dev\reference.cs:line 55
at ConsoleApplication1.Class1.Main(String[] args) in d:\net\client\consoleapplication1\class1.cs:line 66"

Если использую стандартный макрософтовский CSP и TLS, то все работает и исключение не выскакивает. Не могу понять в чем может быть дело, может вы подскажите? Почему именно с использованием КриптоПро СКЗИ выскакивает исключение... Web-сервисы с использование PKI, на основе КриптоПро СКЗИ (который поддерживает множество ключевых носителей) и .NET клиенты на мой взгляд (и думаю, что не только мой) идиальная схема реализации подобных интернет систем, и очень хотелось бы, чтобы разработчики КриптоПро рассмотрели совместную их работу.
Спасибо.
 
Ответы:
21.09.2002 17:11:39Lector
Мне кажется у меня та же проблема.

The operation has timed-out.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Net.WebException: The operation has timed-out.

Она воникает (а может и не возникать, по её желанию ) при попытке работать с сервисом из asp.net страници. При этом, для asp.net приложения сервис всегда доступен (исключая те случаи, когда к нему обратилась asp.net web страница). В чем проблема ещё не выяснил.
23.09.2002 11:41:38Lector
Помогло AspCompat=ture. Такое решение многое объясняет.
27.02.2004 14:53:41Сомов Александр
Можно переопределить метод GetWebRequest у обертки Web-службы на клиенте (например, можно переопределить метод при наследовании, чтобы не менять стандартную обёртку).

protected override WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest webRequest = (HttpWebRequest) base.GetWebRequest(uri);
webRequest.ProtocolVersion = HttpVersion.Version10; // !!!!!!!!!!!!
return webRequest;
}

Без добавления клиентского сертификата такая замена приводит к тому же WebException, но внутреннее исключение у него System.ComponentModel.Win32Exception: The specified data could not be decrypted.

При том сервер настроен устанавливать SSL соединение без клиентского сертификата, и оно нормально устанавливается из Internet Explorer’а.

Если же указать клиентский сертификат из хранилища (вытащить его оттуда можно при помощи WSE, который содержит классы для работы с системными хранилищами, а скачать его можно с microsoft.com), то всё падает с каким-то страшным исключением:

Unhandled Exception: System.Net.WebException: The underlying connection was closed: Could not establish secure channel for SSL/TLS. ---> System.Runtime.InteropServices.COMException (0x80070006): The handle is invalid.
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode, IntPtr errorInfo)
at System.Runtime.InteropServices.Marshal.FreeHGlobal(IntPtr hglobal)
at System.Net.SecurityBufferDescriptor.FreeAllBuffers(Int32 flags)
at System.Net.SSPIWrapper.InitializeSecurityContext(SSPIInterface SecModule, Int64 credential, Int64 context, String targetName, Int32 requirements, Endianness datarep, SecurityBufferClass[] inputBuffers, Int64& newContext, SecurityBufferClass[] outputBuffers, Int32& attributes, Int64& timestamp)
at System.Net.SSPIWrapper.InitializeSecurityContext(SSPIInterface SecModule, Int64 credential, Int64 context, String targetName, Int32 requirements, Endianness datarep, SecurityBufferClass inputBuffer, Int64& newContext, SecurityBufferClass outputBuffer, Int32& attributes, Int64& timestamp)
at System.Net.SecureChannel.GenerateToken(Byte[] input, Byte[]& output)
at System.Net.SecureChannel.NextMessage(Byte[] incoming)
at System.Net.TlsStream.Handshake(ProtocolToken message)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.CheckFinalStatus()
at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult)
at System.Net.HttpWebRequest.GetRequestStream()
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at ConsoleApplication1.TestWebService.Service1.ProcessFile(Byte[] file, Byte[] signature, String id, String password) in c:\documents and settings\somov\my documents\visual studio projects\consoleapplication1\web references\testwebservice\reference.cs:line 37
at ConsoleApplication1.Class1.Main(String[] args) in c:\documents and settings\somov\my documents\visual studio projects\consoleapplication1\class1.cs:line 41

Ну, по крайней мере, уже хоть какая-то диагностика достигнута.