使用客户端证书身份validation连接到Web服务

我已经使用客户端证书身份validation通过SSL连接到Web服务的.p12文件。 我使用cURL成功地在PHP中工作。 这些是我在执行请求时使用的选项:

$headers = array( 'Method: POST', 'Connection: Keep-Alive', 'User-Agent: PHP-SOAP-CURL', 'Content-Type: text/xml; charset=utf-8', 'SOAPAction: "'.$action.'"', ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $location); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $request); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_FAILONERROR, 1); curl_setopt($ch, CURLOPT_SSLCERT, $this->clientcert); curl_setopt($ch, CURLOPT_SSLKEYTYPE, $this->clientcerttype); curl_setopt($ch, CURLOPT_SSLKEY, $this->keyfile); curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $this->keypassword); curl_setopt($ch, CURLOPT_SSLVERSION, 3); $response = curl_exec($ch); 

我现在正在尝试使用C#和.NET执行相同的任务,但我不断收到错误“无法为具有权限的SSL / TLS建立安全通道:’。”。

我似乎没有找到密钥的问题,似乎没有任何信任问题。 但是,某些事情是不对的,某些地方。

我做了一个测试程序,所以我可以测试一个基本的调用是否有效。

 public void StartviaWSHttp() { var binding = new WSHttpBinding(); binding.Security.Mode = SecurityMode.Transport; binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None; binding.Security.Message.NegotiateServiceCredential = false; binding.Security.Message.ClientCredentialType = MessageCredentialType.None; var baseAddress = new Uri("https://:/LineEndpoint1"); var endpointAddress = new EndpointAddress(baseAddress); var client = new LinePortTypeClient(binding, endpointAddress); client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySerialNumber, "00d48a233bf4b77523"); Debug.Assert(client.ClientCredentials.ClientCertificate.Certificate.SerialNumber.ToLower() == "00d48a233bf4b77523"); var header = new ctSoapHeaderMsg(); var response = new object(); client.Open(); var responseCode = client.PerformFunction(ref header, "0893411111", out response); client.Close(); Console.WriteLine("Response Code :" + responseCode); Console.WriteLine("Response :" + response); } 

当我在当前用户的个人/证书中查看证书时,它不会报告任何与信任有关的问题。 在证书信息中,它表示该证书用于以下目的:所有颁发策略和所有应用程序策略。 证书路径只有一个条目,证书状态报告“此证书正常”。

我对这个问题感到茫然。 也许存在信任问题,因为我已经关闭了PHP调用的PEER和HOSTvalidation。 我不确定这是否是C#的一个选项。


更新:(2013年8月9日)我为System.Net和System.Net.Socket设置了一些详细的跟踪。 这是输出的开始。

 System.Net Verbose: 0 : [16124] WebRequest::Create(https://dsl-wholesale-testing.iinet.net.au:50500/LineEndpoint1) System.Net Verbose: 0 : [16124] HttpWebRequest#58508234::HttpWebRequest(https://dsl-wholesale-testing.iinet.net.au:50500/LineEndpoint1#128335743) System.Net Information: 0 : [16124] Current OS installation type is 'Client'. System.Net Information: 0 : [16124] RAS supported: True System.Net Verbose: 0 : [16124] Exiting HttpWebRequest#58508234::HttpWebRequest() System.Net Verbose: 0 : [16124] Exiting WebRequest::Create() -> HttpWebRequest#58508234 System.Net Verbose: 0 : [16124] ServicePoint#36898364::ServicePoint(dsl-wholesale-testing.iinet.net.au:50500) System.Net Information: 0 : [16124] Associating HttpWebRequest#58508234 with ServicePoint#36898364 System.Net Verbose: 0 : [16124] HttpWebRequest#58508234::GetRequestStream() System.Net Information: 0 : [16124] Associating Connection#47995487 with HttpWebRequest#58508234 System.Net.Sockets Verbose: 0 : [16124] Socket#31002555::Socket(AddressFamily#2) System.Net.Sockets Verbose: 0 : [16124] Exiting Socket#31002555::Socket() System.Net.Sockets Verbose: 0 : [16124] Socket#6243847::Socket(AddressFamily#23) System.Net.Sockets Verbose: 0 : [16124] Exiting Socket#6243847::Socket() System.Net.Sockets Verbose: 0 : [16124] DNS::TryInternalResolve(dsl-wholesale-testing.iinet.net.au) System.Net.Sockets Verbose: 0 : [16124] Socket#31002555::Connect(203.173.51.130:50500#-2110560113) System.Net.Sockets Information: 0 : [16124] Socket#31002555 - Created connection from 192.168.190.202:55397 to 203.173.51.130:50500. System.Net.Sockets Verbose: 0 : [16124] Exiting Socket#31002555::Connect() System.Net.Sockets Verbose: 0 : [16124] Socket#6243847::Close() System.Net.Sockets Verbose: 0 : [16124] Socket#6243847::Dispose() System.Net.Sockets Verbose: 0 : [16124] Exiting Socket#6243847::Close() System.Net Information: 0 : [16124] Connection#47995487 - Created connection from 192.168.190.202:55397 to 203.173.51.130:50500. System.Net Information: 0 : [16124] TlsStream#29695768::.ctor(host=dsl-wholesale-testing.iinet.net.au, #certs=0) System.Net Information: 0 : [16124] Associating HttpWebRequest#58508234 with ConnectStream#25001628 System.Net Verbose: 0 : [16124] Exiting HttpWebRequest#58508234::GetRequestStream() -> ConnectStream#25001628 System.Net Verbose: 0 : [16124] ConnectStream#25001628::Write() System.Net Verbose: 0 : [16124] Data from ConnectStream#25001628::Write System.Net Verbose: 0 : [16124] (printing 1024 out of 1206) System.Net Verbose: 0 : [16124] 00000000 : 3C 73 3A 45 6E 76 65 6C-6F 70 65 20 78 6D 6C 6E : <s:Envelope xmln 

System.Net Information: 0 : [16124] TlsStream#29695768::.ctor(host=dsl-wholesale-testing.iinet.net.au, #certs=0)System.Net Information: 0 : [16124] TlsStream#29695768::.ctor(host=dsl-wholesale-testing.iinet.net.au, #certs=0)表明没有获得任何证书可供使用,即使我已将证书附加到client.ClientCredentials.ClientCertificate,但我不确定为什么会发生这种情况或如何使它坚持下去。 证书的任何属性是否必须与我要连接的主机名相匹配?

看来服务器不理解TLS。

我不得不指定SSLv3,via

 System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3; 

正如@ajeh在评论中提到的“transport clientCredentialType = …”为我工作!

      

此外,您需要确保您的IIS应用程序池用户有权读取证书的私钥。