security - .NET 4.0 客户端证书验证错误

标签 security authentication ssl .net-4.0 client-certificates

我有以下代码

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 目录进行验证的,因此客户端无需了解完整链。

问题是,如何禁用这种新行为?

最佳答案

好的,我会在这里提供我自己的答案......

简而言之:您似乎不能将非持久性 CSP 与 .NET 4 一起用于 X509。 IE。您的 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。 Somwhow,私钥在.NET 4.0 中不可导出。 这link帮我修好了。

不过,很高兴知道 3.5 和 4.0 之间发生了什么变化。

关于security - .NET 4.0 客户端证书验证错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7279876/

相关文章:

apache - 从 Apache 到 Wildfly 的 SSL 重定向

ssl - 覆盖 onReceivedSslError 不适用于 Android KitKat Web View

c# - 我可以让 HttpWebRequest 包含 Windows 凭据而不等待 401 挑战吗?

php - 为 PHP REST API 实现简单的身份验证

authentication - Identity Server 4 日志(无效对象名称 'DeviceCodes' )异常

ssl - Apollo federation PUSH 命令跳过 SSLValidation

ios - 在 iOS 中,如何存储允许我与服务器通信的 secret "key"?

mysql - 确保 webapp 用户只能将记录添加到他们拥有的数据库中

security - AWS 云是否提供限制账单金额的选项?

security - Tomcat 保护静态内容