Ошибка проверки сертификата клиента .NET 4.0 - PullRequest
1 голос
/ 02 сентября 2011

У меня есть следующий код

var factory = new ChannelFactory<INewsClient>();
factory.Credentials.ClientCertificate.Certificate = GetCertificate();
factory.Endpoint.Address = new EndpointAddress("https://blabla.com/myservice/");
var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
factory.Endpoint.Binding = binding;
var channel = factory.CreateChannel();
channel.GetNews();

Работает в .NET 3.5, но не в .NET4.0. Биззаре, да? Сертификат, который я использую, не проверяется на локальной машине (без цепочки). В 3.5 действительность сертификата клиента не имеет значения для установления SSL, но при переходе на 4.0 сертификат проверяется перед использованием для SSL. (Я вижу ошибки в журналах событий CAPI2). В результате возникает уродливое исключение SecurityNegotiationException ...

Трассировка стека:

System.ServiceModel.Security.SecurityNegotiationException: Could not establish secure   channel for SSL/TLS with authority 'pep.uat.dialectpayments.com'. ---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
   at System.Net.HttpWebRequest.GetResponse()
   at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
   --- End of inner exception stack trace ---

Server stack trace: 
   at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
   at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
   at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
   at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at ConsoleApplication2.Program.INewsClient.Get()
   at ConsoleApplication2.Program.Main(String[] args) in d:\dev\ConsoleApplication2\Program.cs:line 44

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

Вопрос в том, как отключить это новое поведение?

1 Ответ

1 голос
/ 05 сентября 2011

Хорошо, я предоставлю свой ответ здесь ...

В двух словах: кажется, вы не можете использовать непостоянный CSP с .NET 4 для X509. То есть Ваш CSP должен иметь KeyContainerName, чтобы он работал.

Мой метод GetCertificate () выполнял следующее: (то есть непостоянный)

var certificate = new X509Certificate2(@"C:\public.cer");
var rsa = RSA.Create();
rsa.FromXmlString("<RSAKeyValue>......</RSAKeyValue>");
certificate.PrivateKey = rsa;
return certificate;

Изменение этого параметра приводит к тому, что мой пример работает в 3.5 и 4.0: (Установка KeyContainerName создаст физическую запись в ваших крипто-папках)

var certificate = new X509Certificate2(@"C:\public.cer");
CspParameters parameters = new CspParameters { KeyContainerName = "KeyContainer" };
var rsa = new RSACryptoServiceProvider(parameters);
rsa.FromXmlString("<RSAKeyValue>......</RSAKeyValue>");
certificate.PrivateKey = rsa;
return certificate;

Для простоты я пытался экспортировать закрытый ключ в файл .pfx, но не смог использовать первый подход в .NET 4.0, но мог использовать .NET 3.5. Кстати, закрытый ключ нельзя экспортировать в .NET 4.0. Эта ссылка помогла мне это исправить.

Тем не менее, было бы неплохо узнать, что здесь изменилось между 3.5 и 4.0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...